C++设计模式——观察者模式
观察者模式的使用场景
1.当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立的改变和复用;
2.当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变;
3.观察者模式所做的工作其实就是在接触耦合。让耦合的双方都依赖于抽象,而不依赖于具体,从而使得各自的变化都不会影响到另外一边的变化
#include <iostream> #include <list> using namespace std; //Observer类 抽象观察者,为所有的具体观察者定义一个接口,在得到主题的通知时更新自己。这个接口要做更新接口。 //观察者一般用一个抽象类或者接口实现,更新接口通常包含一个Update()方法 这个方法叫做更新方法。 class Observer { public: virtual void Update(int) = 0; }; //Subject类 可翻译为主题或抽象通知者 一般用一个抽象类或者一个接口实现。他把所有对观察者对象的引用保存 //在一个聚集里,每个主题都可以又任何数量的观察者。抽象主题提供一个接口,可增加或者删除观察者对象 class Subject { public: virtual void Attach(Observer*) = 0; virtual void Detach(Observer*) = 0; virtual void Notify() = 0; }; //ConcreteObserver 具体观察者 实现抽象观察角色所要求的更新接口,以便使本身的状态与主题的状态相协调. //具体观察者角色可以保存一个指向具体主题对象的引用.具体观察者校色通常用一个具体子类实现 class ConcreteObserver : public Observer { public: ConcreteObserver(Subject* pSubject) : m_pSubject(pSubject) {} void Update(int value) { cout << "ConcreteObserver get the update. New State:" << value << endl; } private: Subject* m_pSubject; }; class ConcreteObserver2 : public Observer { public: ConcreteObserver2(Subject* pSubject) : m_pSubject(pSubject) {} void Update(int value) { cout << "ConcreteObserver2 get the update. New State:" << value << endl; } private: Subject* m_pSubject; }; //ConcreteSubject类,叫做具体主题或者具体通知者..将有关状态存入具体观察者对象;在具体主题内部状态改变时...给所有登记过的观察者发出通知. //具体主题对象通常用一个具体子类实现. class ConcreteSubject : public Subject { public: void Attach(Observer* pObserver) { m_ObserverList.push_back(pObserver); } void Detach(Observer* pObserver) { m_ObserverList.remove(pObserver); } void Notify() { std::list<Observer*>::iterator it = m_ObserverList.begin(); while (it != m_ObserverList.end()) { (*it)->Update(m_iState); ++it; } } void SetState(int state) { m_iState = state; } private: std::list<Observer*> m_ObserverList; int m_iState; }; int main() { // Create Subject ConcreteSubject* pSubject = new ConcreteSubject(); // Create Observer Observer* pObserver = new ConcreteObserver(pSubject); Observer* pObserver2 = new ConcreteObserver2(pSubject); // Change the state pSubject->SetState(2); // Register the observer pSubject->Attach(pObserver); pSubject->Attach(pObserver2); pSubject->Notify(); // Unregister the observer pSubject->Detach(pObserver); pSubject->SetState(3); pSubject->Notify(); delete pObserver; delete pObserver2; delete pSubject; system("pause"); return 0; }
参考——https://www.cnblogs.com/carsonzhu/p/5770253.html
参考——大话设计模式
上面这个有不足之处是 万一没有抽象观察者这样的接口,通知功能就完不成了.... 而且每个通知的内容是不一样的
#include <iostream> #include <string> #include <list> using namespace std; class Subject; //抽象观察者 class Observer { protected: string name; Subject* sub; public: Observer(string name, Subject* sub) { this->name = name; this->sub = sub; } virtual void update() = 0; }; //具体的观察者,看股票的 class StockObserver :public Observer { public: StockObserver(string name, Subject* sub) :Observer(name, sub) { } void update(); }; //具体的观察者,看NBA的 class NBAObserver :public Observer { public: NBAObserver(string name, Subject* sub) :Observer(name, sub) { } void update(); }; //抽象通知者 class Subject { protected: list<Observer*> observers; public: string action; virtual void attach(Observer*) = 0; virtual void detach(Observer*) = 0; virtual void notify() = 0; }; //具体通知者,秘书 class Secretary :public Subject { void attach(Observer* observer) { observers.push_back(observer); } void detach(Observer* observer) { list<Observer*>::iterator iter = observers.begin(); while (iter != observers.end()) { if ((*iter) == observer) { observers.erase(iter); } ++iter; } } void notify() { list<Observer*>::iterator iter = observers.begin(); while (iter != observers.end()) { (*iter)->update(); ++iter; } } }; void StockObserver::update() { cout << name << " 收到消息:" << sub->action << endl; if (sub->action == "梁所长来了!") { cout << "我马上关闭股票,装做很认真工作的样子!" << endl; } } void NBAObserver::update() { cout << name << " 收到消息:" << sub->action << endl; if (sub->action == "梁所长来了!") { cout << "我马上关闭NBA,装做很认真工作的样子!" << endl; } } int main() { Subject* dwq = new Secretary(); //创建观察者<br> //被观察的对象 Observer* xs = new NBAObserver("xiaoshuai", dwq); Observer* zy = new NBAObserver("zouyue", dwq); Observer* lm = new StockObserver("limin", dwq); //加入观察队列 dwq->attach(xs); dwq->attach(zy); dwq->attach(lm); //事件 dwq->action = "去吃饭了!";//通知 dwq->notify(); cout << endl; dwq->action = "梁所长来了!"; dwq->notify(); return 0; }