通用编程能力训练:发布-订阅模式

发布-订阅模式核心代码练习:

实现以下参与者:

EventObject

事件对象,用于参数传递

EventSource

事件源,用于触发事件

SubscriberTemplate

订阅器模板,保存客户代码

特殊需求:采用模板实现可定制的客户代码。

心得:

1、为了在 SubscriberTemplate 层面使invoker 的类型无关,使用了 模板构造函数 和 MemberFunctionBounder ,将 invoker 的类型确定时机推到了 MemberFunctionBounder 层。

2、为了能在 SubscriberTemplate 调用客户代码,将 invoker 无关的接口抽象,形成 FunctionBounderBase 层。

3、为了保证 SubscriberTemplate 在赋值、拷贝、删除的时候对 bounder 对象的管理, 在 FunctionBounderBase 层添加了 clone 方法。

扩展:

1、支持非成员函数的客户代码。

2、支持非返回值的客户代码。

3、完善事件触发机制,添加注册、查找事件的功能。

发布-订阅模式练习

// 123.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <vector> template<typename Ret,typename Arg> struct FunctionBounderBase { virtual ~FunctionBounderBase(){} virtual Ret operator ()(Arg) = 0; virtual FunctionBounderBase<Ret,Arg>* clone() = 0; }; template<typename T, typename Ret,typename Arg> struct MemberFunctionBounder : FunctionBounderBase<Ret, Arg> { typedef Ret (T::*MemberFunction)(Arg); MemberFunctionBounder(T* _invoker, MemberFunction _mem_func) : invoker( _invoker) , mem_func( _mem_func) { } Ret operator()(Arg arg) { return (invoker->*mem_func)(arg); } FunctionBounderBase<Ret,Arg>* clone() { return new MemberFunctionBounder<T,Ret,Arg>( invoker, mem_func); } MemberFunction mem_func; T* invoker; }; template<typename Ret,typename Arg> struct SubscriberTemplate { template<typename T> SubscriberTemplate(T* _invoker, Ret (T::*mem_func)(Arg) ): bounder( new MemberFunctionBounder<T,Ret,Arg>(_invoker,mem_func)) { printf("new MemberFunctionBounder\n"); } ~SubscriberTemplate() { printf("delete MemberFunctionBounder\n"); delete bounder; bounder = 0; } SubscriberTemplate( const SubscriberTemplate<Ret,Arg>& other) : bounder(other.bounder->clone()) { printf("Copy Constructor MemberFunctionBounder\n"); } SubscriberTemplate<Ret,Arg>& operator =( const SubscriberTemplate<Ret,Arg>& other) { bounder = other.bounder->clone(); return *this; } Ret operator ()(Arg arg) { return (*bounder)(arg); } FunctionBounderBase<Ret,Arg>* bounder; }; struct EventObject { EventObject():m_handled(false){} ~EventObject(){}; bool m_handled; }; struct EventSource { typedef SubscriberTemplate<bool, EventObject*> Subscriber; typedef std::vector<Subscriber> Subscribers; void subscriberEvent(Subscriber subscriber) { mSubscribers.push_back(subscriber); } void fireEvent(EventObject* e) { bool ret = false; for( Subscribers::iterator it = mSubscribers.begin(); it != mSubscribers.end(); ++it) { Subscriber* subscriber = &(*it); ret |= (*subscriber)(e); } } Subscribers mSubscribers; }; struct Base { bool fun(EventObject* e) { printf("Base::fun(EventObject* e)\n"); return true; } }; int _tmain(int argc, _TCHAR* argv[]) { Base s; EventSource* source = new EventSource; source->subscriberEvent( EventSource::Subscriber(&s, &Base::fun)); EventObject e; source->fireEvent(&e); delete source; getchar(); return 0; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值