c++设计模式概述之观察者
代码写的不够规范,目的是缩短篇幅,实际情况请不要这样做
1、概述
观察者模式,类比生活中的场景,比如看电影,观众对播放的内容有不同的反应, 再比如订阅,公众号订阅,只要你订阅了其公众号,你就会收到其推送。再比如,天气,人们针对天气变化的反应也是不一样的。
观察者模式的主要角色如下。
A、抽象主题角色:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。
B、具体主题角色:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
C、抽象观察者角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。
D、具体观察者角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。
总结,主要2个对象: 观察者和被观察对象。
2、观察者抽象类
// 观察者 class observer { public: // 观察者的反应 virtual void respond() = 0; };
3、观察者类
这里,准备了两个观察者,
// 观察者A class observerA : public observer { public: void respond() { std::cout << "\n观察者A做出反应\n"; } }; // 观察者B class observerB : public observer { public: void respond() { std::cout << "\n观察者B做出反应\n"; } };
4、抽象对象(目标)
// 抽象目标 class subject { public: // 添加新的观察者 virtual void add(observer *pobs) { if (!pobs) return; std::list<observer*>::iterator it = std::find(_plist_observer.begin(), _plist_observer.end(), pobs); // 没有找到,则添加 if (it == _plist_observer.end()) _plist_observer.push_back(pobs); else cout << "\n对象已经存在,无需重复添加\n"; } // 删除观察者 virtual void remove(observer *pobs) { if (!pobs) return; int size = _plist_observer.size(); if (0 < size) _plist_observer.remove(pobs); } // 通知所有观察者 virtual void notify_observer() = 0; protected: // 可能有多个观察者 std::list<observer*> _plist_observer; };
5、具体目标类
// 对象A, class subjectA :public subject { public: // 实现,并通知观察者 void notify_observer() { std::cout << "\n\n\n-----请注意,目标A已经变化了----\n"; for each (auto item in _plist_observer) item->respond(); } };
6、调用示例
1 // 调用 2 void call_observer() 3 { 4 // 1、创建观察者 和 被观察的目标 5 std::unique_ptr<observer> pobsA(new(std::nothrow) observerA); 6 std::unique_ptr<observer> pobsB(new(std::nothrow) observerB); 7 std::unique_ptr<subject> psubA(new(std::nothrow) subjectA); 8 9 if (!pobsA || !pobsB || !psubA) 10 { 11 std::cout << "\n 创建观察者或者目标失败\n\n"; 12 return; 13 } 14 15 // 2、被观察目标添加观察者 16 psubA->add(pobsA.get()); 17 psubA->add(pobsB.get()); 18 std::cout << "1、目标变化了,观察者反应:"; 19 psubA->notify_observer(); 20 21 // 3、解除观察者 22 psubA->remove(pobsA.get()); 23 std::cout << "\n\n2、解除观察者A,目标变化,观察者反应"; 24 psubA->notify_observer(); 25 }
7、输出