zoukankan      html  css  js  c++  java
  • 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.一种松耦合的分层插件系统的设计和实现


  • 相关阅读:
    使用JQUERY UI中的dialog对话框提示,如果点击确认,执行服务端代码的基本代码
    C#开源资源大汇总
    Net下图片的常见存储与读取
    asp.net中各种对像使用jquery的赋值的方式
    js放大图片
    W3C DOM异常对象DOMException介绍
    js创建函数的方式介绍
    实现自定义的input file标签
    SECURITY_ERR:DOM Exception 18:canvas getImageData putImageData问题
    javascript讲解
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6470351.html
Copyright © 2011-2022 走看看