设计模式之观察者模式(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;}
实例代码运行结果:
观察者模式的最重要目标是接触耦合,让耦合的双发都依赖于抽象,而不应该依赖于具体,从而使得各自的变化不会影响到另一边的变化。(依赖倒换原则)
- 设计模式之观察者模式(C++)
- 设计模式之观察者模式(c++)
- 设计模式--观察者模式(C++)
- 设计模式--观察者模式(C++)
- 设计模式--观察者模式(C++)
- 设计模式----观察者模式Observer(C++)
- 设计模式---观察者模式(C++)
- 设计模式之观察者模式 (原创)
- 设计模式之Observer(观察者模式)
- 设计模式之Observer(观察者模式)
- 【设计模式】之观察者模式(Observer)
- 设计模式之--观察者模式(Observer)
- 设计模式之观察者模式(二)
- 设计模式之观察者模式(Obsever)
- 设计模式之观察者(Observer)模式
- 设计模式之观察者(observer)模式
- 设计模式之观察者模式(Observer)
- 设计模式之观察者模式(一)
- HashMap,LinkedHashMap,TreeMap的区别+如何替换LinkedHashMap键位的值+RecyclerView单条更新
- RABBITMQ集群与负载均衡
- 242. Valid Anagram
- POJ2376Cleaning Shifts(贪心)
- Material Design: NavigationView FlaotingActionBar SnackBar的使用
- 设计模式之观察者模式(C++)
- uc/os-iii学习笔记-任务切换
- Celery在Django下使用的内存泄漏问题
- An 8-year-old English girl who called out a major retailer as
- 纯HTML+CSS编写动态下拉菜单
- mmap()
- EXCEL排序
- java socket的网络编程一些小结
- HDU 3336 Count the string