观察者模式
上篇通过EAP(中介者),完成了各部门间的沟通混乱的问题。 有些部门的工作情况需要有别的部门的工作结果觉得。 事例: 公司希望做0库存挤压,这时需要生产部门可以随时响应销售情况。
# 场景分析
这里的场景是 生产部门对 销售部门的随时响应,不不是销售部门有什么事就可以指派生产部门。
而是说明,在某一个生产部门需要的关注的点上要及时的通知生产部门,以便生产部门可以及时的做出调整。
这里的提示是针对销售的业务做的提示; 生产部门的响应也是基于生产的业务上做出调整。
# 实现
# 接口类
观察者接口:
class AddObServer
{
public:
~AddObServer() {}
virtual void doAdd(int number) = 0;
};
1
2
3
4
5
6
7
2
3
4
5
6
7
观察者管理类接口:
class Subject
{
public:
Subject() {}
~Subject() {}
void addObServer(AddObServer* observer)
{
m_oAddObServer.push_back(observer);
}
void removeObServer(AddObServer* observer)
{
m_oAddObServer.remove(observer);
}
protected:
list<AddObServer*> m_oAddObServer;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 实现类
观察者接口实现:
class MarketingDepartment : public Subject
{
public:
MarketingDepartment()
: Subject() {}
~ MarketingDepartment() {}
void sell(int number)
{
cout << "市场部买了 " << number << " 根冰棍!" << endl;
for (auto var : m_oAddObServer)
{
var->doAdd(number);
}
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
观察者管理类接口实现:
class ProductDepartment : public AddObServer
{
public:
ProductDepartment()
: AddObServer() {}
~ProductDepartment() {}
virtual void doAdd(int number) override
{
cout << "生产部门:准备生产 " << number << " 根冰棍。" << endl;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# main函数
int main(int argc, char* argv[])
{
MarketingDepartment oMarketingDepartment;
ProductDepartment oProductDepartment;
oMarketingDepartment.addObServer(&oProductDepartment);
oMarketingDepartment.sell(2);
return 0;
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
运行结果:
# 代码位置
仓库位置:https://github.com/su-dd/demo.git (opens new window)
代码位置:设计模式/Observer (opens new window)
# 感悟
观察者模式是一个常见的设计模式。
优点: 1、建立了触发机制,为了解决一些响应式的业务流。
2、调用者和被调用者进行了抽象解耦,调用者将不知情自己将调用什么。
当有业务需要用【每当...... 就.....】 描述时,可以考虑使用观察者模式。
如果不希望调用者被阻塞,可以才有异步模式执行触发器。
局限: 1、需要避免循环调用 观察者模式也是一个需要谨慎使用的模式,由于观察者模式的响应式触发;导致难以在代码中追查到完整的业务流。
试想如果一个业务完全有触发器堆砌的程序,整个程序的业务就处于:A触发B,B触发C,C触发...的链式触发中。 当多个业务链有交叉时,如何让复杂业务不做循环调用这种简单要求也会变成世纪难题。
2、一个事件上挂的触发器太多,可能导致原来代码的效率下降。
3、观察者无法知道需要观察对象的状态,需要提供额外的能力实现。
编辑 (opens new window)
上次更新: 2023/04/09, 11:59:04