zoukankan      html  css  js  c++  java
  • 使用小技巧使子功能模块不污染主框架

      使用C++开发在做消息分发的时候我们经常会遇到这样的场景,我们为每个消息设计了单独的处理类或者处理函数,并用一个映射去维护这样的对应关系,当消息来的时候,我们遍历这个映射表,找到对应的处理函数,进而处理消息。

      我们可能遇到了这样的设计

    #include"case1.h"
    #include"case2.h"
    #include"case3.h"
    #include"case4.h"
    #include"case5.h"
    
    void HandleManage::reghandle(){
         _mhandles["cmd_1"] = new case1_handle();
         _mhandles["cmd_2"] = new case2_handle();
         _mhandles["cmd_3"] = new case3_handle();
         _mhandles["cmd_4"] = new case4_handle();
         _mhandles["cmd_5"] = new case5_handle();
    }

     这样设计满足了我们的要求,但是会带来两个问题

       1、随着迭代开发的进行,会有大量新的case进来,这样regHandle会变得非常长,而且同时会有大量的case已经不再有用,占用了映射表的同时也降低了消息映射的查找效率

       2、当我们不想使用旧的case的时候,注册模块需要手动删除,维护起来比较困难

    为了解决这两个问题我打算重新设计handle管理模块:

    HandleManage.h

    #pragma once
    #include <map>
    #include <string>
    #include "IHandle.h"
    using namespace std;
    class HandleManager
    {
    public:
        static HandleManager* instance() {
            if (_pInstance == NULL) {
                _pInstance = new HandleManager();
            }
            return _pInstance;
        }
    
        void regHandle(const string& cmd, IHandle* handle);
        void unregHandle(const string& cmd);
        IHandle * getHandle(const string& cmd);
        void onHandle(const string& cmd);
    private:
        map<string, IHandle*> _map_handle;
        HandleManager(){}
        static HandleManager* _pInstance;
    };

    HandleManage.cpp

    #include "HandleManager.h"
    
    HandleManager* HandleManager::_pInstance = NULL;
    
    void HandleManager::regHandle(const string& cmd, IHandle* handle) {
        _map_handle[cmd] = handle;
    }
    
    void HandleManager::unregHandle(const string& cmd) {
        if (_map_handle.find(cmd) != _map_handle.end()) {
            _map_handle.erase(cmd);
        }
    }
    
    IHandle * HandleManager::getHandle(const string& cmd) {
        if (_map_handle.find(cmd) != _map_handle.end()) {
            return _map_handle[cmd];
        }
        return NULL;
    }
    
    void HandleManager::onHandle(const string& cmd) {
        IHandle * pHandle = getHandle(cmd);
        if (NULL != pHandle) {
            pHandle->handle(cmd);
        }
    }

    IHandle.h 消息处理的统一接口

    #pragma once
    #include<string>
    using namespace std;
    class IHandle
    {
    public:
        virtual void handle(const string& cmd) = 0;
    };

    当我们每开发一个case的时候为期建立唯一的文件夹(f方便makefile添加编译路径)

    以一个case为例:

    case_1.h

    #pragma once
    #include <string>
    #include "../manager/HandleManager.h"
    using namespace std;
    const static string strCmd = "case_1";
    class Case_1:public IHandle,public IConfig
    {
    public:
        static Case_1* instance() {
            if (_pInstance == NULL) {
                _pInstance = new Case_1();
            }
    
            if (_pInstance != NULL) {
                HandleManager::instance()->regHandle(strCmd, _pInstance);
    
            }
            return _pInstance;
        }
        void handle(const string& cmd);
    private:
        static Case_1* _pInstance;
        Case_1(){}
    };
    
    static Case_1 * spInstance = Case_1::instance();

    case_1.cpp

    #include "Case_1.h"
    #include <iostream>
    
    Case_1* Case_1::_pInstance = NULL;
    
    void Case_1::handle(const string& cmd) {
        cout <<"handle:"<< cmd << endl;
    }

    测试代码如下:

    #include "test/manager/HandleManager.h"
    using namespace std;
    
    int main(){
    
        HandleManager::instance()->onHandle("case_1");
        HandleManager::instance()->onHandle("case_2");
    
        system("pause");
    }

      可以看到在测试入口和handleManager都没有关于具体case的任何代码,而是在每个case模块将处理函数注入到消息映射表中,同时利用外部变量的特性,在运行最开始时就能被调用

           当有新的需求case合入或者旧的case过期的时候,我们只需修改Makefile就能保证最后的进程只包含有效的case代码

  • 相关阅读:
    Find cmd
    splitFile2SmallFile
    IPC-->PIPO
    Thread and shared lock
    Python Thread related
    linux 文件系统
    linux commands
    关于 gnome3 无法显示应用程序所有界面的反馈
    Windows 网络编程
    常见端口 HTTP代码
  • 原文地址:https://www.cnblogs.com/wanzaixiaoxin/p/11862752.html
Copyright © 2011-2022 走看看