设计模式之观察者模式(C++)

来源:互联网 发布:淘宝手机店铺首页尺寸 编辑:程序博客网 时间:2024/04/19 08:35

观察者模式(Observer):定义了对象间的一种一对多的关系,当一个对象改变时,所有依赖他的对象都得到通知并自动更新。

动机:

将一个系统划分成一系列相互协作的类有一个常用的副作用:需要维护相关对象间的一致性,我们不希望为了维护一致而是的各类紧密耦合,因为主要降低了系统的可复用性,因此利用观察者模式可以描述建立一种各层次之间的关系的模型,当被依赖的某个对象的状态发生变更时,所有依赖的对象的状态都得到更新。当前很多大型代码结构中都用到了一种事件机制,这种事件机制其实就是观察者模式的一种,订阅者订阅目标的某个时期,当目标触发该事件时通知订阅者。如Windows开发中我们订阅系统的鼠标单击事件,当我们鼠标单击我们程序的窗口时,操作系统就会发布鼠标单击系统给相应的订阅者,订阅者执行相应的操作。


适用性:

1、当一个抽象模型有两个方面,其中一个方面依赖另外一个方面。将这二者封装在独立的对象中以使它们可以独立的改变和复用。

2、当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象有待改变。

3、当一个对象必须通知其他对象,而它又不能假定其他对象时谁。换言之,你不希望对象之间是紧密耦合的。


通用观察者模式UML类图

Subject(目标):抽象的目标类,提供了一个抽象的Notify,和增加/删除对象引用的的接口。

ConcreteSubject:具体目标类,实现了抽象目标类的接口,同时增加了设置对象状态属性和获取状态属性的方法。

注意的是:目标类维护了一个观察者的对象列表,需要订阅Subject对象状态改变的类都必须向具体的目标对象注册自己,当具体目标类对象状态改变时,根据维护的观察者对象列表来通知观察者对象改变。


Obserber(观察者/订阅者):观察者抽象类,提供了一个更新状态的抽象接口。

ConcterteObserver1/ConcreteObserver2:具体观察者类,实现抽象类的接口,并增加了一个显示当前状态的函数。


实例代码如下:

Observer.h

#ifndef Observer_h_#define Observer_h_#include <iostream>#include <list>class Observer;const int NET_STAT_UNCONNET = 0;const int NET_STAT_LISTENING = 1;const int NET_STAT_CONNCTED = 2;class Subject{public:virtual ~Subject(){};virtual bool Attach(Observer*)=0;virtual bool Detach(Observer*)=0;virtual void Notify() = 0;void SetState(int state){ this->m_state = state; }int GetState(){ return m_state; }protected:int m_state;};class ConcreteSubject :public Subject{public:ConcreteSubject();virtual ~ConcreteSubject(){};void Notify();virtual bool Attach(Observer*);virtual bool Detach(Observer*);private:std::list<Observer*> m_observer_List;};class Observer{public:virtual ~Observer(){};virtual void Update(Subject*)=0;void ShowState(){ std::cout << "state: " << m_state << std::endl; }protected:int m_state;};class ConcrtrObserver1:public Observer{public:virtual void Update(Subject*);ConcrtrObserver1();virtual ~ConcrtrObserver1(){};};class ConcrtrObserver2 :public Observer{public:virtual void Update(Subject*);ConcrtrObserver2();virtual ~ConcrtrObserver2(){};};#endif

Observer.cpp

#include "Observer.h"#include <algorithm>ConcreteSubject::ConcreteSubject(){m_state = NET_STAT_UNCONNET;}bool ConcreteSubject::Attach(Observer* pObser){m_observer_List.push_back(pObser);std::cout << "Insert an Observer\n";return true;}bool ConcreteSubject::Detach(Observer* pObser){std::list<Observer*>::iterator it;for (it = m_observer_List.begin(); it != m_observer_List.end(); it++){if (*it == pObser){m_observer_List.erase(it);std::cout << "Erase an observer\n";break;}}return true;}void ConcreteSubject::Notify(){std::list<Observer*>::iterator it;for (it = m_observer_List.begin(); it != m_observer_List.end(); it++){(*it)->Update(this);}}ConcrtrObserver1::ConcrtrObserver1(){m_state = NET_STAT_UNCONNET;}void ConcrtrObserver1::Update(Subject* pSubject){this->m_state = pSubject->GetState();ShowState();}ConcrtrObserver2::ConcrtrObserver2(){m_state = NET_STAT_UNCONNET;}void ConcrtrObserver2::Update(Subject* pSubject){this->m_state = pSubject->GetState();ShowState();}

客户端代码:

#include"Observer.h"int main(){ConcrtrObserver1 *pObser1 = new ConcrtrObserver1();ConcrtrObserver2 *pObser2 = new ConcrtrObserver2();ConcrtrObserver1 *pObser3 = new ConcrtrObserver1();ConcrtrObserver2 *pObser4 = new ConcrtrObserver2();ConcreteSubject *pSubject = new ConcreteSubject();pSubject->Attach(pObser1);pSubject->Attach(pObser2);pSubject->Attach(pObser3);pSubject->Attach(pObser4);pSubject->SetState(NET_STAT_LISTENING);pSubject->Notify();pSubject->Detach(pObser3);pSubject->SetState(NET_STAT_CONNCTED);pSubject->Notify();delete pObser1;delete pObser2;delete pObser3;delete pObser4;delete pSubject;return 0;}


实例代码运行结果:



观察者模式的最重要目标是接触耦合,让耦合的双发都依赖于抽象,而不应该依赖于具体,从而使得各自的变化不会影响到另一边的变化。(依赖倒换原则)


1 0
原创粉丝点击