设计模式之观察者模式
设计模式之观察者模式(Observer Pattern)
模式定义
观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。
观察者模式是一种对象行为型模式。
类图
代码
class Observer;
class Subject {
public:
virtual void attach(Observer *pObserver) = 0;
virtual void detach(Observer *pObserver) = 0;
virtual void notify() = 0;
virtual ~Subject() {}
};
class ConcreteSubject : public Subject {
public:
void attach(Observer *pObserver) override;
void detach(Observer *pObserver) override;
void notify() override;
void setStatus(int status)
{
_status = status;
}
int getStatus() const
{
return _status;
}
private:
list<Observer *> _obList;
int _status;
};
class Observer {
public:
virtual void update(int) = 0;
virtual ~Observer() { }
};
class ConcreteObserver1 : public Observer {
public:
void update(int value)
{
cout << "ConcreteObserver1: value = " << value << endl;
}
};
class ConcreteObserver2 : public Observer {
public:
void update(int value)
{
cout << "ConcreteObserver2: value = " << value << endl;
}
};
void ConcreteSubject::attach(Observer *pObserver) {
_obList.push_back(pObserver);
}
void ConcreteSubject::detach(Observer *pObserver)
{
for(auto it = _obList.begin(); it != _obList.end(); ++it)
{
if(*it == pObserver)
{
_obList.remove(pObserver);
break;
}
}
}
void ConcreteSubject::notify()
{
for(auto &ob : _obList)
{
ob->update(_status);
}
}
void test()
{
unique_ptr<ConcreteSubject> pSubject(new ConcreteSubject());
unique_ptr<Observer> pObserver1(new ConcreteObserver1());
unique_ptr<Observer> pObserver2(new ConcreteObserver2());
pSubject->setStatus(1);
pSubject->attach(pObserver1.get());
pSubject->attach(pObserver2.get());
pSubject->notify();
pSubject->detach(pObserver2.get());
pSubject->setStatus(2);
pSubject->notify();
}
观察者模式的优点
- 观察者模式可以实现表示层和数据逻辑层的分离,并定义了稳定的消息更新传递机制,抽象了更新接口,使得可以有各种各样不同的表示层作为具体观察者角色。
- 观察者模式在观察目标和观察者之间建立一个抽象的耦合。
- 观察者模式支持广播通信。
- 观察者模式符合“开闭原则”的要求。
观察者模式的缺点
- 如果一个观察目标对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
- 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
- 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
使用场景
- 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
- 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
- 一个对象必须通知其他对象,而并不知道这些对象是谁。
- 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南