观察者模式 C++实现
观察者模式
观察者模式又叫做发布-订阅(Publish/Subsribe)模式。
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己。
在以下任一情况下都可以使用观察者模式:
当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立的改变和复用;
当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变;
当一个对象必须通知其它对象,而它又不能假定其它对象是谁;也就是说,你不希望这些对象是紧密耦合的。
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(); //创建观察者 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; }