您的位置:首页 > 编程语言 > C语言/C++

利用委托加观察者模式实现老板状态变化通知C++

2016-03-19 22:39 656 查看
之前写过利用观察者模式实现老板状态变化通知的程序, 当时书本上介绍了当观察者对象所提供的接口不同时候, 也就是各个观察者类并不是派生自同一个观察者接口CIObserver的时候, 观察者模式就遇到一些问题, 在C#中, 我们可以借助委托机制很轻松的解决。然而C++并不提供现成的委托机制, 需要我们自己编写相应代码实现委托的功能, 主要是利用模板的参数推导功能。

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: