目录
观察者模式(Observer)定义了一种一对多的依赖关系,让多个观察者对象同事监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。【DP】
观察者模式(Observer Pattern)是一种行为型设计模式,它定义了对象之间的一对多依赖关系,使得当一个对象状态发生改变时,所有依赖它的对象都会自动收到通知并更新。
观察者模式的主要角色包括:
(1)Subject(目标):被观察的对象,它维护了一个观察者列表,并提供了添加、删除和通知观察者的方法。
(2)Observer(观察者):观察目标的对象,它定义了接收通知并进行相应操作的方法。
(3)ConcreteSubject(具体目标):具体的被观察对象,继承或实现了Subject接口,可以有多个不同的具体目标。
(4)ConcreteObserver(具体观察者):具体的观察者对象,继承或实现了Observer接口,可以有多个不同的具体观察者。
(1)当一个对象的改变需要同时通知其他对象,并且不知道具体有多少个对象需要通知时。
(2)当一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将这两个方面封装在独立的对象中,使它们可以独立地改变和复用时。
1)解耦性:观察者模式将目标和观察者解耦,使得它们可以独立地变化。
2)扩展性:可以很方便地增加新的观察者和目标,符合开闭原则。
3)可以实现一对多的依赖关系,一个目标可以有多个观察者。
1)观察者过多时,会导致通知时间增加,影响性能。
2)观察者和目标之间有循环依赖时,可能会导致循环调用,需要注意避免。
-
- #include
- #include
-
- // 观察者接口
- class Observer
- {
- public:
- virtual void update(int data) = 0;
- };
-
- // 具体观察者A
- class ConcreteObserverA : public Observer
- {
- public:
- void update(int data) override
- {
- std::cout << "ConcreteObserverA received update: " << data << std::endl;
- }
- };
-
- // 具体观察者B
- class ConcreteObserverB : public Observer
- {
- public:
- void update(int data) override
- {
- std::cout << "ConcreteObserverB received update: " << data << std::endl;
- }
- };
-
- // 目标类
- class Subject
- {
- private:
- int data;
- std::vector
observers; -
- public:
- void attach(Observer* observer)
- {
- observers.push_back(observer);
- }
-
- void detach(Observer* observer)
- {
- for (auto it = observers.begin(); it != observers.end(); ++it)
- {
- if (*it == observer)
- {
- observers.erase(it);
- break;
- }
- }
- }
-
- void notify()
- {
- for (auto observer : observers)
- {
- observer->update(data);
- }
- }
-
- void setData(int newData)
- {
- data = newData;
- notify();
- }
- };
-
- int main()
- {
- Subject subject;
- ConcreteObserverA observerA;
- ConcreteObserverB observerB;
-
- subject.attach(&observerA);
- subject.attach(&observerB);
-
- subject.setData(10);
-
- subject.detach(&observerA);
-
- subject.setData(20);
-
- return 0;
- }
在上述示例中,我们定义了Observer接口和两个具体观察者类ConcreteObserverA和ConcreteObserverB。Subject类作为目标类,维护了一个观察者列表,并提供了attach、detach和notify等方法。在主函数中,我们创建了一个Subject对象和两个具体观察者对象,并通过attach方法将它们注册到Subject中。然后,通过setData方法改变Subject的数据,从而触发通知并更新观察者。