观察者模式
观察者模式定义
观察者模式(Observe Pattern)也叫做发布订阅模式(Publish/subscribe),定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
观察者模式通用类图
Subject被观察者
定义被观察者必须实现的职责,它必须能够动态地增加(Attach),取消观察者(Detach),并通知观察者(Notify)。它一般是抽象类。
Observer 观察者
观察者接收到消息后,即进行update操作,对接收到的信息进行处理。
ConcreteSubject 具体的被观察者
定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知。
ConcreteObserver 具体的观察者
观察者模式的优点
观察者和被观察者之间是抽象耦合
观察者模式通过定义抽象的被观察者基类和观察者基类,从而降低了具体的观察者类和被观察者类之间的耦合。实际的观察操作(绑定,解绑,通知,响应等)都在抽象基类中定义,具体的被观察者和观察者则互相不需要了解对象的实现细节。
建立一套触发机制,可以形成触发链。
缺点
观察者模式需要考虑开发效率和运行效率的问题,一个被观察者,多个观察者,开发和调试就会比较复杂。
举例,在java中已有java.util.Observable实现类和java.util.Observer接口,具体的被观察者类只需要继承Observable类,而观察者只需要实现Observer接口。
C++通用源码:
#include <iostream> #include <list> using namespace std; class Observer{ public: virtual void Update()=0; virtual ~Observer(){}; }; class Subject{ protected: list<Observer *> observers; public: virtual void Attach(Observer *o){observers.push_back(o);}; virtual void Detach(Observer *o){observers.remove(o);}; virtual void Notify(){ for(list<Observer *>::iterator it=observers.begin();it!=observers.end();it++) { (*it)->Update(); } } virtual ~Subject(){}; }; class ConcreteSubject:public Subject{ public: ~ConcreteSubject(){ for(list<Observer *>::iterator it=observers.begin();it!=observers.end();it++) { delete *it; } }; void doSomething(){ cout<<"具体被观察者在干活,通知观察者..."<<endl; Notify(); } }; class ConcreteObserver:public Observer{ public: void Update(){ cout<<"被观察者在干活,好样的!"<<endl; } }; class ConcreteObserver1:public Observer{ public: void Update(){ cout<<"咦!还有别的观察者!"<<endl; } }; int main() { ConcreteSubject subject; //创建被观察者 subject.Attach(new ConcreteObserver()); //创建一个观察者并绑定到被观察者上 Observer * observer1 = new ConcreteObserver1(); subject.Attach(observer1);//创建一个其它子类型的观察者,也绑定到这个被观察者上 subject.doSomething(); //两个观察者均能收到消息 subject.Detach(observer1); //解绑定第二个观察者。 delete observer1; subject.doSomething(); return 0; }
运行结果
昨夜星辰昨夜风,画楼西畔桂堂东。
身无彩凤双飞翼,心有灵犀一点通。
隔座送钩春酒暖,分曹射覆蜡灯红。
嗟余听鼓应官去,走马兰台类转蓬。