观察者模式(Observer Pattern)
有一个例子,电子屏幕和内部显示器上的股票价格要随着股票价格改变而改变。
使用C++来实现这个逻辑
#include <iostream> // 显示器类 class Mointor{ public: // 展示股票价格 void print(int v){ std::cout << "Mointor: " << v << std::endl; } }; // 电子屏类 class Billboard{ public: // 展示股票价格 void display(int v){ std::cout << "Billboard: " << v << std::endl; } }; // 股票类 class stack{ public: stack(Mointor* mointor, Billboard* billboard, int v): prices(v), mointor(mointor), billboard(billboard){} // 设置股票价格 void setPrice(int v){ prices = v; mointor->print(v); billboard->display(v); } private: int prices; Mointor* mointor; Billboard* billboard; }; int main(){ // 创建显示器对象 Mointor* mointor = new Mointor(); // 创建电子屏对象 Billboard* billboard = new Billboard(); // 创建股票对象 stack* stock = new stack(mointor, billboard, 10); // 设置股票价格 stock->setPrice(20); return 0; }
这种实现方式,类之间紧耦合,当显示介质(Mointor或Billboard)发生变化时或新的显示媒介加入,Stock
类会频繁修改。
采用观察者模型修改上述代码:
- 抽象主题(Subject)角色:也叫抽象目标类或目标接口类,它提供了一个用于保存观察者对象的聚集类(List)和增加(attch)、删除观察者(detach)对象的方法,以及通知所有观察者的抽象方法。
- 具体主题(Stack)(被观察目标)角色:也叫具体目标类,它是被观察的目标,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
- 观察者接口(Observer)角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法(update),当接到具体主题的更改通知时被调用。
- 具体观察者(Mointor or Billboard)角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。
#include <iostream> #include <list> class Stock; class Observer{ public: Observer(Stock* stock): stock(stock){} virtual ~Observer(){} virtual void update(int v)=0; private: Stock* stock; }; class Subject{ public: // 添加观察者 void attach(Observer* o){ observers.push_back(o); } // 移除观察者 void detach(Observer* o){ observers.remove(o); } // 通知观察者 void notify(int v){ for(auto o:observers){ o->update(v); } } private: std::list<Observer*> observers; }; // 股票价格类 class Stock{ public: // 添加观察者 void attach(Observer* o){ subject.attach(o); } // 移除观察者 void detach(Observer* o){ subject.detach(o); } // 通知观察者 void notify(int v){ subject.notify(v); } // 设置股票价格 void setPrice(int v){ price = v; notify(price); } private: int price; Subject subject; }; // 显示器类 class Mointor: public Observer{ public: Mointor(Stock* stock): Observer(stock){} ~Mointor(){} // 展示股票价格 void print(int v){ std::cout << "Mointor: " << v << std::endl; } void update(int v) override{ print(v); } }; // 电子屏类 class Billboard: public Observer{ public: Billboard(Stock* stock): Observer(stock){} // 展示股票价格 void display(int v){ std::cout << "Billboard: " << v << std::endl; } void update(int v) override{ display(v); } }; int main(){ // 创建股票和显示器 Stock* stock = new Stock(); Mointor* monitor = new Mointor(stock); Billboard* billboard = new Billboard(stock); // 添加观察者 stock->attach(monitor); stock->attach(billboard); // 设置股票价格 stock->setPrice(10); stock->setPrice(20); // 移除观察者 stock->detach(monitor); stock->setPrice(30); delete stock; delete monitor; delete billboard; return 0; };
参考:
https://segmentfault.com/a/1190000040530952
DY:EfficLab