视频网站建设,营销型网站建设个人,php是世界上最好的语言,成都工装装修设计公司1.定义 在GOF的《设计模式#xff1a;可复用面向对象软件的基础》一书中对观察者模式是这样定义的#xff1a;定义对象的一种一对多的依赖关系#xff0c;当一个对象的状态发生改变时#xff0c;所有依赖于它的对象都得到通知并被自动更新。当一个对象发生了变化#xff0…1.定义 在GOF的《设计模式可复用面向对象软件的基础》一书中对观察者模式是这样定义的定义对象的一种一对多的依赖关系当一个对象的状态发生改变时所有依赖于它的对象都得到通知并被自动更新。当一个对象发生了变化关注它的对象就会得到通知这种交互也成为发布-订阅publish-subscribe。
2.组成结构
Subject目标目标知道它的观察者可以有任意多个观察者观察用一个目标提供注册和删除观察者对象的接口。Observer观察者为所有观察目标的观察者对象提供一个公共的更新接口。ConcreteSubject具体目标将有关状态的情况广播给各ConcreteObserver对象。ConcreteObserver具体观察者维护一个指向ConcreteSubject对象的指针用于当具体观察者初始化时直接存入ConcreteSubject对象初始化就订阅ConcreteSubject主题存储有有关状态这些状态应与目标的状态保持一致实现Observer公共更新接口以便使自身状态和目标状态保持一致。
3.示例代码
#include iostream
#include list
using std::cout;
using std::endl;
using std::cin;class Observer
{
public:virtual ~Observer() {};virtual void Update(int) 0;
};class Subject
{
public:virtual ~Subject() {};virtual void Attach(Observer*) 0;virtual void Detach(Observer*) 0;virtual void Notify() 0;
};class ConcreteObserver : public Observer
{
private:Subject* _pSubject;public:ConcreteObserver(Subject* pSubject) :_pSubject(pSubject){//在目标中注册当前观察者此处的观察者是广义上的观察者目标并不知道具体谁要观察它目标只进行广播即可this-_pSubject-Attach(this);cout Im the observer \ 1 \.\n;}void Update(int value) override{cout ConcreteObserver get the update.New State: value endl;}
};class ConcreteObserver2 : public Observer
{
private:Subject* _pSubject;public:ConcreteObserver2(Subject* pSubject) :_pSubject(pSubject){//在目标中注册当前观察者此处的观察者是广义上的观察者目标并不知道具体谁要观察它目标只进行广播即可this-_pSubject-Attach(this);cout Im the observer \ 2 \.\n;}void Update(int value) override{cout ConcreteObserver2 get the update.New State: value endl;}
};class ConcreteSubject :public Subject
{
private:std::listObserver* _pObserverList;int _iState;
public:void SetState(int state){_iState state;}void Attach(Observer* pObserver) override{_pObserverList.push_back(pObserver);}void Detach(Observer* pObserver) override{_pObserverList.remove(pObserver);}void Notify() override{auto begin _pObserverList.begin();auto end _pObserverList.end();while (begin ! end){(*begin)-Update(_iState);begin;}}
};int main()
{//创建目标ConcreteSubject* pSubject new ConcreteSubject();//创建观察者Observer* pObserver new ConcreteObserver(pSubject);Observer* pObserver2 new ConcreteObserver2(pSubject);//改变当前状态pSubject-SetState(2);//广播给所有广义上的观察者pSubject-Notify();//去除某个观察者pSubject-Detach(pObserver);//改变当前状态pSubject-SetState(3);//重新广播pSubject-Notify();//结束释放对象delete pObserver;delete pObserver2;delete pSubject;return 0;
}
4.使用说明
意图定义对象间的一种一对多的依赖关系当一个对象的状态发生改变时所有依赖于它的对象都会得到通知并被自动更新。
主要解决一个对象状态改变并给其它对象通知的问题而且要考虑到易用和低耦合保证高度的协作。
何时使用一个对象目标对象的状态发生改变所有的依赖对象观察者对象都将得到通知进行广播通知。
如何解决使用面向对象技术可以将这种依赖关系弱化。
关键代码在抽象类里有一个arrayList存放观察者们。
应用实例1、拍卖的时候拍卖师观察最高价格然后通知给其它竞价者竞价。2、西游记里面悟空请求菩萨降服红孩儿菩萨洒了一地水找来一个老乌龟这个老乌龟就是观察者菩萨是被观察者他观察菩萨这个动作。
优点1、观察者和被观察者是抽象耦合的。2、建立一套触发机制。
缺点1、如果一个被观察者对象有很多的直接和间接的观察者的话将所有的观察者都通知到会花费很多时间。2、如果在观察者和观察目标之间有循环依赖的话观察目标会触发它们之间进行循环调用可能导致系统崩溃。3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的而仅仅只是知道观察目标发生了变化。
使用场景
一个抽象模型有两个方面其中一个方面发依赖于另外一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。一个对象的改变将导致其它一个或多个对象发生改变而不知道具体有多少对象将发生改变可以降低对象之间的耦合度。一个对象必须通知其他对象而并不知道这些对象是谁。需要在系统中创建一个触发链A对象的行为将影响B对象B对象的行为将影响C对象……可以使用观察者模式创建一种链式触发机制。
注意事项1、应避免循环引用。2、如果顺序执行某一观察者错误会导致系统卡壳一般采用异步方式多线程。
引用
C观察者模式_c observer-CSDN博客