观察者模式(Observer)又叫发布-订阅(Public/Subscribe)模式.
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个
主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
观察者模式的结构图
观察者模式一般实现:
- // Observer.cpp : Defines the entry point for the console application.
- //
- #include "stdafx.h"
- #include "assert.h"
- #include <iostream>
- #include <string>
- #include <list>
- #include <algorithm>
- using namespace std;
- class Observer
- {
- private:
- string name;
- public:
- virtual bool operator==(const Observer obj) const
- {
- if(obj.name == name)
- return true;
- else
- return false;
- }
- virtual void Update()
- {
- assert(false);
- }
- };
- void fun(Observer * obj)
- {
- obj->Update();
- }
- class Subject
- {
- private:
- list<Observer*> observers;
- //增加观察者
- public:
- virtual void Attach(Observer *observer)
- {
- observers.push_back(observer);
- }
- //移除观察者
- virtual void Detach(Observer *observer)
- {
- observers.remove(observer);
- }
- //通知
- virtual void Notify()
- {
- for_each(observers.begin(), observers.end(), fun);
- }
- };
- //具体通知者
- class ConcreteSubject : public Subject
- {
- private:
- string subjectState;
- //具体通知者状态
- public:
- string GetSubjectState()
- {
- return subjectState;
- }
- void SetsubjectState(string value)
- {
- subjectState = value;
- }
- };
- class ConcreteObserver : public Observer
- {
- private:
- string name;
- string observerState;
- ConcreteSubject * subject;
- public:
- ConcreteObserver(ConcreteSubject *_subject, const string &_name)
- {
- subject = _subject;
- name = _name;
- }
- virtual bool operator==(const ConcreteObserver obj) const
- {
- if(obj.name == name)
- return true;
- else
- return false;
- }
- //更新
- virtual void Update()
- {
- observerState = subject->GetSubjectState();
- cout << "观察者" << name << "的新状态是" << observerState << endl;
- }
- ConcreteSubject * GetConcreteSubject()
- {
- return subject;
- }
- SetConcreteSubject(ConcreteSubject * value)
- {
- subject = value;
- }
- };
- int main()
- {
- //观察者模式
- ConcreteSubject * CSub = new ConcreteSubject();
- ConcreteObserver *ConcreteObserver1 = new ConcreteObserver(CSub, "X");
- CSub->Attach(ConcreteObserver1);
- ConcreteObserver *ConcreteObserver2 = new ConcreteObserver(CSub, "Y");
- CSub->Attach(ConcreteObserver2);
- ConcreteObserver *ConcreteObserver3 = new ConcreteObserver(CSub, "Z");
- CSub->Attach(ConcreteObserver3);
- CSub->SetsubjectState("ABC");
- CSub->Notify();
- delete ConcreteObserver1;
- delete ConcreteObserver2;
- delete ConcreteObserver3;
- return 0;
- }
观察者模式的具体实现
- #include "stdafx.h"
- #include "assert.h"
- #include <iostream>
- #include <string>
- #include <list>
- #include <algorithm>
- using namespace std;
- class Observer;
- //通知者接口
- class Subject
- {
- private:
- string action;
- public:
- virtual void Attach(Observer * observer){};
- virtual void Detach(Observer * observer){};
- void Notify();
- virtual string GetSubjectState(){assert(false);return 0;}
- virtual void SetSubjectState(string &value ){assert(false);}
- };
- //观察者模式的特点:
- //将一个系统分割成一系
- //抽象观察者
- class Observer
- {
- protected:
- string name;
- Subject *sub;
- public:
- Observer(string _name, Subject *_sub)
- {
- name = _name;
- sub = _sub;
- }
- virtual bool operator==(const Observer obj) const
- {
- if(obj.name == name)
- return true;
- else
- return false;
- }
- virtual void Update(){cout << "Observer!" << endl; }
- };
- void fun(Observer *obj)
- {
- obj->Update();
- }
- class Secretary : public Subject
- {
- //同事列表
- private:
- list<Observer*> observers;
- string action;
- //增加
- public:
- virtual void Attach(Observer *observer)
- {
- observers.push_back(observer);
- }
- //减少
- virtual void Detach(Observer *observer)
- {
- observers.remove(observer);
- }
- //通知
- virtual void Notify()
- {
- for_each(observers.begin(), observers.end(), fun);
- }
- //前台状态
- string GetSubjectState()
- {
- return action;
- }
- void SetSubjectState(string value )
- {
- action = value;
- }
- };
- class Boss : public Subject
- {
- //同事列表
- private:
- list<Observer*> observers;
- string action;
- public:
- //增加
- virtual void Attach(Observer *observer)
- {
- observers.push_back(observer);
- }
- //减少
- virtual void Detach(Observer *observer)
- {
- observers.remove(observer);
- }
- //通知
- virtual void Notify()
- {
- for_each(observers.begin(), observers.end(), fun);
- }
- //老板状态
- virtual string GetSubjectState()
- {
- return action;
- }
- void SetSubjectState(string value)
- {
- action = value;
- }
- };
- //看股票的同事
- class StockObserver : public Observer
- {
- public:
- StockObserver(string name, Subject *sub)
- : Observer(name, sub)
- {
- }
- virtual void Update()
- {
- cout << sub->GetSubjectState() << name << "关闭股票行情,继续工作!" ;
- }
- };
- //看NBA的同事
- class NBAObserver : public Observer
- {
- public:
- NBAObserver(string name, Subject *sub)
- : Observer(name, sub)
- {
- }
- virtual void Update()
- {
- cout << sub->GetSubjectState() << name << "关闭NBA直播,继续工作!" ;
- }
- };
- int main()
- {
- //老板胡汉三
- Boss * huhansan = new Boss();
- //看股票的同事
- StockObserver * Yangbailao = new StockObserver("杨白劳", huhansan);
- //看NBA的同事
- NBAObserver * Xier = new NBAObserver("喜儿", huhansan);
- huhansan->Attach(Yangbailao);
- huhansan->Attach(Xier);
- huhansan->Detach(Yangbailao);
- //老板回来
- huhansan->SetSubjectState("我胡汉三回来了!");
- //发出通知
- huhansan->Notify();
- return 0;
- }
观察者模式的不足
我们看观察者模式,发现抽象通知者和抽象观察者之间还有很大的耦合性。
这里我们可以通过使用委托来来解决这个问题
委托就是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同
的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值。委托可以看作是
对函数的抽象,是函数的'类',委托的实例将代表一个具体的函数。
一个委托可以搭载多个方法,所有方法被依次唤起。可以使得委托对象所搭载的方法并不
属于同一个类。
- #include "stdafx.h"
- #include "assert.h"
- #include <iostream>
- #include <string>
- #include <list>
- #include <algorithm>
- using namespace std;
- class Observer;
- //通知者接口
- class Subject
- {
- private:
- string action;
- public:
- virtual void Attach(Observer * observer){};
- virtual void Detach(Observer * observer){};
- void Notify();
- virtual string GetSubjectState(){assert(false);return 0;}
- virtual void SetSubjectState(string &value ){assert(false);}
- };
- //通知者接口
- class Subject
- {
- public:
- void Notify();
- string GetSubjectState(){};
- void SetSubjectState(){};
- };
- class StockObserver;
- typedef void (*EventHandler)();
- //事件处理程序的委托
- class Secretary : public Subject
- {
- //声明一事件Update,类型为委托EventHandler
- public:
- void Update(EventHandler eh)
- {
- _eh = eh;
- }
- void Notify()
- {
- (*_eh)();
- }
- string GetSubjectState()
- {
- return action;
- }
- void SetSubjectState(string value)
- {
- action = value;
- }
- private:
- string action;
- EventHandler _eh;
- };
- class Boss : public Subject
- {
- //声明一事件Update,类型为委托EventHandler
- public:
- void Update(EventHandler eh)
- {
- _eh = eh;
- }
- void Notify()
- {
- (*_eh)();
- }
- string GetSubjectState()
- {
- return action;
- }
- void SetSubjectState(string value)
- {
- action = value;
- cout << action << endl;
- }
- private:
- string action;
- EventHandler _eh;
- };
- //看股票的同事
- class StockObserver
- {
- private:
- string name;
- Subject *sub;
- public:
- StockObserver(string _name, Subject *_sub): name(_name), sub(_sub)
- {
- }
- //关闭股票行情
- static void CloseStockMarket()
- {
- cout << "关闭股票行情,继续工作!" ;
- }
- };
- //看NBA的同事
- class NBAObserver
- {
- private:
- string name;
- Subject *sub;
- public:
- NBAObserver(string _name, Subject *_sub): name(_name), sub(_sub)
- {
- }
- //关闭NBA直播
- static void CloseNBADirectSeeding()
- {
- cout << "关闭NBA直播,继续工作!";
- }
- };
- int main()
- {
- //老板胡汉三
- Boss *huhansan = new Boss();
- //看股票的同事
- StockObserver * Yangbailao = new StockObserver("杨白劳", huhansan);
- //看NBA的同事
- NBAObserver * Xier = new NBAObserver("喜儿", huhansan);
- //老板回来
- huhansan->SetSubjectState("我胡汉三回来了!");
- huhansan->Update(Yangbailao->CloseStockMarket);
- //发出通知
- huhansan->Notify();
- huhansan->Update(Xier->CloseNBADirectSeeding);
- //发出通知
- huhansan->Notify();
- return 0;
- }