观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听一个主题对象。这个主题对象在状态发生变化时,会通知所有的观察者对象,使它们能够自动更新自己。
在观察者模式中,有三个角色:
- 主题(Subject):主题对象知道它的观察者,并提供注册和删除观察者的接口。
- 观察者(Observer):为那些在目标发生改变时需要获得通知的对象定义一个更新接口。
- 具体观察者(ConcreteObserver):存储与主题的状态自恰的状态。具体观察者角色实现了抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态 像协调。
#include
#include // 定义抽象主题类
class Subject
{
public:virtual ~Subject() {}// 注册观察者virtual void registerObserver(Observer* observer) = 0;// 删除观察者virtual void removeObserver(Observer* observer) = 0;// 通知观察者virtual void notifyObservers() = 0;
};// 定义抽象观察者类
class Observer
{
public:virtual ~Observer() {}// 更新方法virtual void update(Subject* subject) = 0;
};// 定义具体主题类
class ConcreteSubject : public Subject
{
public:ConcreteSubject() : state_(0) {}// 获取状态int getState() const { return state_; }// 设置状态void setState(int state){state_ = state;// 状态改变,通知所有的观察者notifyObservers();}void notifyObservers(){// 遍历所有的观察者,调用更新方法for (Observer* observer : observers_){observer->update(this);}}void registerObserver(Observer* observer){observers_.push_back(observer);}void removeObserver(Observer* observer){// 从观察者列表中删除观察者for (auto it = observers_.begin(); it != observers_.end(); ++it){if (*it == observer){observers_.erase(it);break;}}}private:int state_;std::vector observers_;
};// 定义具体观察者类
class ConcreteObserver : public Observer
{
public:ConcreteObserver(ConcreteSubject* subject, int id) : subject_(subject), id_(id){// 注册观察者subject_->registerObserver(this);}~ConcreteObserver(){// 删除观察者subject_->removeObserver(this);}// 更新方法void update(Subject* subject){if (subject == subject_){std::cout << "Observer " << id_ << ": subject state is " << subject_->getState() << std::endl;}}private:ConcreteSubject* subject_;int id_;
};int main()
{ConcreteSubject* subject = new ConcreteSubject();// 创建观察者Observer* observer1 = new ConcreteObserver(subject, 1);Observer* observer2 = new ConcreteObserver(subject, 2);// 改变主题的状态subject->setState(1);// 再次改变主题的状态subject->setState(2);// 删除观察者delete observer1;delete observer2;delete subject;return 0;
}
观察者模式有以下几个优点:
- 观察者模式可以实现表示层和数据逻辑层的分离,并使得表示层和数据逻辑层的变化独立。
- 观察者模式支持广播通信。
- 观察者模式简化了对象之间的依赖关系,每个对象只需保存有关自己的状态,无需保存有关其他对象的状态,这避免了系统中对象之间的耦合关系。
观察者模式也有一些缺点:
- 观察者模式会增加系统的复杂度,因为可能会有很多的观察者,所以需要维护这些观察者之间的注册关系。
- 如果一个观察者对象的更新操作比较慢,会导致系统的效率降低。
- 观察者模式没有相应的机制让观察者知道所观察的目
主题对象与观察者之间存在较强的耦合关系,一旦建立了这种关系,很难撤销。
主题对象的更新需要通知所有的观察者,如果观察者数量较多,会导致性能下降。
观察者之间存在循环依赖关系时,可能会导致系统崩溃。
主题对象的状态发生变化时,可能会导致观察者的状态发生变化,这样就可能会出现无限递归的情况。