利用委托加观察者模式实现老板状态变化通知C++
2016-03-19 22:39
656 查看
之前写过利用观察者模式实现老板状态变化通知的程序, 当时书本上介绍了当观察者对象所提供的接口不同时候, 也就是各个观察者类并不是派生自同一个观察者接口CIObserver的时候, 观察者模式就遇到一些问题, 在C#中, 我们可以借助委托机制很轻松的解决。然而C++并不提供现成的委托机制, 需要我们自己编写相应代码实现委托的功能, 主要是利用模板的参数推导功能。
UML图:
运行效果图:
实现代码:
delegate_non_params.h
delegate.h
subject.h
Mainsubject.h
MainObserver.h
main.cpp
UML图:
运行效果图:
实现代码:
delegate_non_params.h
#ifndef _DELEGATE_NON_PARAMS_H_ #define _DELEGATE_NON_PARAMS_H_ #include <list> using std::list; /************************************************************************/ /* 不带参数的委托机制实现 */ /************************************************************************/ class IDelegate{ public: virtual void notify() = 0; }; template<class ObserverType> class IDelegateAgent : public IDelegate{ typedef void (ObserverType::*Handler)(void); public: IDelegateAgent(ObserverType * type, Handler handler){ this->handler = handler; this->type = type; } void notify(){ (type->*handler)(); } private: Handler handler; ObserverType * type; }; class CIEvent{ public: void operator+= (IDelegate * delegate){ mylist.push_front(delegate); } void operator-= (IDelegate * delegate){ for (auto iter = mylist.begin(); iter != mylist.end(); iter++){ if (*iter == delegate){ mylist.erase(iter); break; } } } void operator()(){ for (auto item : mylist){ item->notify(); } } private: list<IDelegate *> mylist; }; #endif // _DELEGATE_NON_PARAMS_H_
delegate.h
#ifndef _DELEGATE_H_ #define _DELEGATE_H_ #include <list> using std::list; /************************************************************************/ /* 带1个参数的委托机制实现 */ /************************************************************************/ template<class ArgsType> class IDelegate{ public: virtual void notify(ArgsType args) = 0; }; template<class ObserverType, class ArgsType> class IDelegateAgent : public IDelegate<ArgsType>{ typedef ObserverType::(*Handler)(ArgsType args); public: IDelegateAgent(ObserverType * type, Handler handler){ this->type = type; this->handler = handler; } void notify(ArgsType args){ (*handler)(args); } private: Handler handler; ObserverType * type; }; template <class ArgsType> class CIEvent{ public: void operator+= (IDelegate * delegate){ mylist.push_front(delegate); } void operator-= (IDelegate * delegate){ for (auto iter = mylist.begin(); iter != mylist.end(); iter++){ if (*iter == delegate){ mylist.erase(iter); break; } } } void operator()(ArgsType args){ for (auto item : mylist){ item->notify(args); } } private: list<IDelegate *> mylist; }; #endif // _DELEGATE_H_
subject.h
#ifndef _SUBJECT_H_ #define _SUBJECT_H_ #include <string> /************************************************************************/ /* 主题基类 */ /************************************************************************/ class CISubject{ public: std::string State() const { return state; } void State(std::string val) { state = val; } virtual void Notify() = 0; private: std::string state; }; #endif // _SUBJECT_H_
Mainsubject.h
#ifndef _MAINSUBJECT_H_ #define _MAINSUBJECT_H_ #include "Subject.h" #include "delegate_non_params.h" /************************************************************************/ /* CBoss 通知者将通知事件委托给了 CIEvent */ /************************************************************************/ class CBoss : public CISubject{ public: void Notify(){ Event(); } public: CIEvent Event; }; /************************************************************************/ /* CSecretary 通知者将通知事件委托给了 CIEvent */ /************************************************************************/ class CSecretary : public CISubject{ public: void Notify(){ Event(); } public: CIEvent Event; }; #endif // _MAINSUBJECT_H_
MainObserver.h
#ifndef _MAINOBSERVER_H_ #define _MAINOBSERVER_H_ #include "Subject.h" #include <string> #include <iostream> /************************************************************************/ /* 股票观察者 */ /************************************************************************/ class CStockObserver{ public: CStockObserver(CISubject * subject, std::string name) : subject(subject), name(name){} void closeMarket(){ std::cout << subject->State() << "," << name << "关闭股票行情, 认真工作" << std::endl; } private: CISubject * subject; std::string name; }; /************************************************************************/ /* NBA 观察者 */ /************************************************************************/ class CNBAObserver{ public: CNBAObserver(CISubject * subject, std::string name) : subject(subject), name(name){} void closeNBA(){ std::cout << subject->State() << "," << name << "关闭NBA直播, 认真工作" << std::endl; } private: CISubject * subject; std::string name; }; #endif // _MAINOBSERVER_H_
main.cpp
#include "delegate_non_params.h" #include "MainObserver.h" #include "MainSubject.h" #include <iostream> #include <memory> using namespace std; int main(){ shared_ptr<CBoss> boss(new CBoss); shared_ptr<CStockObserver> stock(new CStockObserver(boss.get(), "lisi")); shared_ptr<CNBAObserver> nba(new CNBAObserver(boss.get(), "zhangsan")); shared_ptr<IDelegateAgent<CStockObserver>> stockAgent(new IDelegateAgent<CStockObserver>(stock.get() ,&CStockObserver::closeMarket)); shared_ptr<IDelegateAgent<CNBAObserver>> nbaAgent(new IDelegateAgent<CNBAObserver>(nba.get() ,&CNBAObserver::closeNBA)); boss->Event += stockAgent.get(); boss->Event += nbaAgent.get(); boss->State("老子回来了, 小的们准备接风酒啊"); boss->Notify(); system("pause"); return 0; }
相关文章推荐
- C++实验2-模拟ATM
- C语言之清空缓存区
- C++运算符优先级
- C++指针
- 哈希表的C++实现
- C++第二次实验1-标准体重
- 自己用C语言写PIC32单片机的serial bootloader
- 一起talk C栗子吧(第一百二十五回:C语言实例--显示文件名和行号)
- C语言的输入与输出
- c++第二次实验项目四
- 哈夫曼树的创建和编码
- C++中关于一维、二维、三维动态数组的定义
- C++——虚函数
- C++并行开发Pthread之线程(一)
- c++杂记
- C++ 编写WebService服务
- C/C++中基本数据类型学习
- ros与下位机通信常用的c++ boost串口应用--22
- 百练2972:确定进制
- <<Effective C++>>读书笔记(三)