一种基于总线思想的软件构架

一种基于总线思想的软件框架

项目上学到的,直接上实例代码,使用总线类来实现模块之间通信

/// Invoker抽象类
class IComInvoker
{
public:
	virtual ~IComInvoker(){};
	//! 调用接口,可以使用boost::any代替QVariant
	virtual QVariant Invoke(QVariant args[], int nArgNum) = 0;
	//! 判断目标参数类型是否合法
	virtual bool CheckMethodValid(QVariant args[], int nArgNum) = 0;
}
类成员指针声明形式:typedef bool (ClassA::*Method)(int)
赋值:	  		Method method = &ClassA::Func;
调用方式:		pA->*method(1)
///! 调用器具体类,这里只演示一个形参的Invoker1,实际项目中会构造多个形参的Invoker2、Invoker3...
template<class R, class ObjT, class T1>
class Invoker1: public IComInvoker
{
	typedef R (ObjT::*Method)(T1);
private:
	ObjT* m_obj;
	Mehtod m_memFunc;
public:
	Invoker1(ObjT* obj, Method method):m_obj(obj),m_memFunc(method){}
	QVariant Invoke(QVariant args[], int nArgNum)
	{
		if(nArgNum != 1)
			return R();
		QVariant v0 = args[0];
		return (m_obj->*m_memFunc)(v0.value<T1>());
	}
	bool CheckMethodValid(QVariant args[], int nArgNum)
	{
		//校验参数是否为目标类型,略
	}
}
///! 总线类,实际项目中做成单例,维护一个总线
class SvrBus
{
typedef QMap<QString, QMap<QString, IComInvoker*>> ComMethods;
public:
	IComInvoker* GetInvoker(QString strModule, QString strInvokerName)
	{
		return m_mapMethods[strModule][strInvokerName];
	}
	void RegisterMethod(QString strModule, QString strMethodName, IComInvoker* invoker)
	{
		//多个模块注册时考虑加锁保证线程安全
		m_mapMethods[strModule][strMethodName] = invoker;
	}
private:
	ComMethods m_mapMethods;
}
///! 需要注册到总线的模块
class Module1
{
public:
	Module1(SvrBus& svrBus)
	{
		//! 此处可以进一步做成宏来简化每个模块的动作
		IComInvoker* invoker = (IComInvoker*)new Invoker1<void, Module1, int>(this, &Module1::Func)
		svrBus.RegisterMethod("Module1", "Func", invoker);
	}
private:
	void Func(int m);
}

///!外部调用该模块示例(该处可进一步封装为SvrWrap类)
IComInvoker* invoker = svrBus.GetInvoker("Module1", "Func");
QVariant args[1];
args[0] = 888;
if(invoker->CheckMethodValid(args, 1))
{
	invoker->Invoke(args, 1);
}

通过这种框架,两个独立模块之间仅依赖SvrBus进行通信,可以做到尽可能解耦,在调用时进行类型检查等安全措施,不会因为兼容问题造成闪退。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值