• boost::any在降低模块之间耦合性的应用


    作者:朱金灿

    来源:http://blog.csdn.net/clever101

         

           在开发大型系统中,遵循这样一个原则:模块之间低耦合,模块内高内聚。比如系统中模块有界面模块和算法模块两种,一般是界面模块调用算法模块,这样的话界面模块依赖于算法模块。现在我要实现这样界面和算法分离,即界面模块不依赖于算法模块。除了界面模块不依赖于算法模块,我要应对的另一个挑战是算法参数是不确定的,就是说要容纳任意的参数类型。      

     

          为此我找到了boost::any。boost::any的好处是它能容纳任意类型的数据。它可以很方便的进行模块间函数之间不确定参数传递。具体做法是这样的:

     

    1. 在系统底层定义一个算法基类CBaseAlgo,其接口如下:

    // BaseAlgo.h
    #include <string>
    #include <boost/any.hpp>
    
    class CBaseAlgo
    {
    public:
    
    	CBaseAlgo(std::string& strID);
    
    	virtual ~CBaseAlgo(void);
    
        virtual bool run(boost::any& anyData);
    
    
    protected:
    
    	std::string m_strID;
    
    };
    
    // BaseAlgo.cpp
    CBaseAlgo::CBaseAlgo(std::string& strID)
    {
    	m_strID = strID;
    }
    
    CBaseAlgo::~CBaseAlgo(void)
    {
    }
    
    bool CBaseAlgo::run( boost::any& anyData )
    {
        return false;
    }

    2.所有的算法模块都有一个算法类,算法类都派生自CBaseAlgo,示例如下:

    // AlgoDemo1.h
    
    #include "BaseAlgo.h"
    #include "AlgoParameter.h"
    
    class CAlgoDemo1: public CBaseAlgo
    {
    public:
    	CAlgoDemo1(std::string& strID);
    
    	virtual ~CAlgoDemo1(void);
    
    	bool run(boost::any& anyData);
    };
    
    // AlgoDemo1.cpp
    #include "AlgoDemo1.h"
    
    CAlgoDemo1::CAlgoDemo1(std::string& strID):CBaseAlgo(strID)
    {
    }
    
    CAlgoDemo1::~CAlgoDemo1(void)
    {
    }
    
    bool CAlgoDemo1::run( boost::any& anyData )
    {
    	if(anyData.type() == typeid(stAlgoParameter1))  
    	{
    		stAlgoParameter1 ret = boost::any_cast<stAlgoParameter1>(anyData);
    		ret.m_nNo = 100;
    		ret.m_strName = "John";
    		// 如果需要返回值,那就需要重新对anyData进行赋值
    		anyData = ret;
    	}
    	return true;
    }
    
    
    

    其中AlgoParameter.h定义了算法参数结构,代码如下:

    // AlgoParameter.h
    
    struct stAlgoParameter1
    {
    	std::string m_strName;
    	int m_nNo;
    };

    3. 然后在调用算法模块的地方,这里假定为main函数,这样调用:

    // main.cpp
    
    #include <boost/any.hpp>
    #include "BaseAlgo.h"
    #include "AlgoParameter.h"
    
    // 根据算法ID找到算法类,具体是返回创建的算法类的指针
    CBaseAlgo* GetAlgoObj(std::string& strAlgoID)
    {
    // 这里动态加载算法模块,算法模块都导出一个接口来创建算法对象,具体不予实现
    }
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	stAlgoParameter1 info;
    	boost::any anyData = info;
    	info = boost::any_cast<stAlgoParameter1>(anyData);
    	// 调用动态规划算法
    	std::string strAlgoID = "DynamicProgramming"; 
        CBaseAlgo*   pAlgoObj = GetAlgoObj(strAlgoID);
    	if(NULL!=pAlgoObj)
    		pAlgoObj->run(anyData);
            
    	getchar();
    	return 0;
    }

            这样设计的好处是算法模块和调用算法的模块只需要包含定义参数结构体的头文件AlgoParameter.h,调用算法的模块并不依赖于算法模块。同时boost::any的特性保证了可以传递任意类型参数。

     

    参考文献:

     

    1.boost源码剖析之:泛型指针类any之海纳百川

     

    2.一种松耦合的分层插件系统的设计和实现


  • 相关阅读:
    Angular(一)
    go微服务系列(四)
    导包路径
    django导入环境变量 Please specify Django project root directory
    动手动脑三
    动手动脑二
    大柱
    日报
    验证码
    动手动脑
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6470351.html
Copyright © 2020-2023  润新知