在C++中,传统的业务分发。总要写一大串的switch-case,并且每次添加新业务时。都要在原有的switch-case里加一个分支,这就违反了设计模式中的开放封闭原则。

下面这样的方案,就全然去除了switch-case。每当要加入业务模块时。仅仅要写一个TEST_MODULE(index, name)就能够了。

思路非常easy,直接上代码:

  1. #include <iostream>
  2. #include <string>
  3. #include <map>
  4. using namespace std;
  5. //业务模块,第一个參数是模块ID,第二个是模块名称
  6. //用了C语言的一些技巧。嘿嘿
  7. #define TEST_MODULE(index, name) \
  8. void test_##name(int num); \
  9. TempFunction fun_##name(index, test_##name); \
  10. void test_##name(int num)
  11. //模块中所使用的回调函数
  12. typedef void (*MODULE_FUNCTION)(int num);
  13. //模块管理类(单例)
  14. class ModuleFactory
  15. {
  16. private:
  17. map<int, MODULE_FUNCTION> m_ModuleMap;
  18. ModuleFactory() { }
  19. ~ModuleFactory() { }
  20. public:
  21. static ModuleFactory *GetInstance()
  22. {
  23. static ModuleFactory instance;
  24. return &instance;
  25. }
  26. //返回总的业务个数
  27. int BusinessCount()
  28. { return m_ModuleMap.size(); }
  29. //载入业务(假设业务号有反复,就输出一条信息,然后退出程序)
  30. void AddBusiness(int index, MODULE_FUNCTION fun)
  31. { m_ModuleMap[index] = fun; }
  32. //运行业务
  33. void RunFunction(int index, int num)
  34. {
  35. map<int, MODULE_FUNCTION>::iterator iter = m_ModuleMap.find(index);
  36. if( iter == m_ModuleMap.end() )
  37. cout << "no this module: " << index << endl;
  38. else
  39. iter->second(num);
  40. }
  41. };
  42. //暂时类。利用了“全局变量的构造函数必然会会在main函数之前被运行这个特点
  43. class TempFunction
  44. {
  45. public:
  46. TempFunction(int index, MODULE_FUNCTION fun)
  47. { ModuleFactory::GetInstance()->AddBusiness(index, fun); }
  48. };
  49. //三个业务模块
  50. //每当要加入业务模块时,仅仅要写一个TEST_MODULE(index, name)就能够了
  51. TEST_MODULE(1, aaa)
  52. {
  53. cout << "aaa: " << num << endl;
  54. }
  55. TEST_MODULE(2, bbb)
  56. {
  57. cout << "bbb: " << num << endl;
  58. }
  59. TEST_MODULE(3, ccc)
  60. {
  61. cout << "ccc: " << num << endl;
  62. }
  63. //測试样例
  64. int main()
  65. {
  66. int index, num;
  67. while( cin >> index >> num )
  68. {
  69. ModuleFactory::GetInstance()->RunFunction(index, num);
  70. }
  71. return 0;
  72. }

C++的一种业务分发方案(另类的工厂模式)的更多相关文章

  1. 根据业务自己设计的.NET工厂模式架构

    最近项目的架构需要做调整优化,根据业务需要写了一个简单的工厂模式架构 项目介绍:整个系统分为三大平台(这里用A,B,C来标示),每个平台又细分为多个APP客户端(每个APP都有appid来区分) 因为 ...

  2. java23种设计模式(二)抽象工厂模式

    我们接着上一章的工厂方法模式继续学习一下抽象工厂模式. 抽象工厂模式:在工厂模式中,如果有多个产品,则就是抽象工厂模式. 例子: 有一个工厂开了两个子公司,专门用来生产电脑配件键盘和鼠标,一个是联想工 ...

  3. GOF业务场景的设计模式-----工厂模式

    定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类. 工厂方法模式 基本代码 interface IProduct { public void produ ...

  4. java三种工厂模式

    适用场合: 7.3 工厂模式的适用场合 创建新对象最简单的办法是使用new关键字和具体类.只有在某些场合下,创建和维护对象工厂所带来的额外复杂性才是物有所值.本节概括了这些场合. 7.3.1 动态实现 ...

  5. atitit.短信 验证码  破解  v3 p34  识别 绕过 系统方案规划----业务相关方案 手机验证码  .doc

    atitit.短信 验证码  破解  v3 p34  识别 绕过 系统方案规划----业务相关方案 手机验证码  .doc 1. 手机短信验证码 vs 图片验证码 安全性(破解成本)确实要高一些1 1 ...

  6. Python几种并发实现方案的性能比较

    http://blog.csdn.net/permike/article/details/54846831 Python几种并发实现方案的性能比较 2017-02-03 14:33 1541人阅读 评 ...

  7. 对比7种分布式事务方案,还是偏爱阿里开源的Seata,真香!(原理+实战)

    前言 这是<Spring Cloud 进阶>专栏的第六篇文章,往期文章如下: 五十五张图告诉你微服务的灵魂摆渡者Nacos究竟有多强? openFeign夺命连环9问,这谁受得了? 阿里面 ...

  8. 正确修改MySQL最大连接数的三种好用方案

    以下的文章主要介绍的是正确修改MySQL最大连接数的三种好用方案,我们大家都知道MySQL数据库在安装完之后,默认的MySQL数据库,其最大连接数为100,一般流量稍微大一点的论坛或网站这个连接数是远 ...

  9. 最经常使用的两种C++序列化方案的使用心得(protobuf和boost serialization)

    导读 1. 什么是序列化? 2. 为什么要序列化?优点在哪里? 3. C++对象序列化的四种方法 4. 最经常使用的两种序列化方案使用心得 正文 1. 什么是序列化? 程序猿在编写应用程序的时候往往须 ...

随机推荐

  1. ABP模块配置

    介绍 我们知道ABP中模块的配置都是通过模块的Configuration属性来设置的.例如在模块的生命周期方法中可以进行一系列的配置 审计 MQ Redis....也可以替换一些ABP默认配置 通常我 ...

  2. JS中,根据div数值判断弹出窗口

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  3. zookeeper 安装配置注意事项

    zoo.cfg 1.server.1/2/3  有几台配置几个 ​2.配置好hosts映射之后可以用node1替代IP地址 3.dataLogDir  下面配置的logs 的目录一定要创建 4.dat ...

  4. oracle --(三)数据段(segment)

    基本关系:数据库---表空间---数据段---分区---数据块 数据段(segment)段(segment)由一系列的extent组成.通常一张表是一个segment. Oracle中的段可以分成4种 ...

  5. css知多少(9)——float下篇(转)

    css知多少(9)——float下篇   float内容比较多,咱们分上.下两篇来介绍,上篇已经写完,这是下篇.建议大家先把上篇看了,再来看下文,精彩内容不要掠过啊. 1. 清除float <上 ...

  6. 前端学习笔记2017.6.12 CSS控制DIV

    前一篇文章中用div布局了豆瓣东西的页面,如果用html代码表示的话大概是这个样子的 <!DOCTYPE html><html><head></head> ...

  7. beforeFilter()

    在控制器每个动作之前执行,可以方便地检查有效的会话,或者检查用户的权限. function beforeFilter() { parent::beforeFilter(); if(empty($thi ...

  8. 数据结构 lucky_ming幸运的小明

    问题描述 在快速排序过程中, 每次会找一个划分值, 将小于划分值的放到其左边, 大于划分值的放右边, 然后再依次递归左右两边, 对子序列进行同样的操作, 直到子序列为空则停止操作.最后就得到了有序的序 ...

  9. Java50道经典习题-程序40 字符串排序

    题目:根据字符串内字符的ASCII码值对字符串数组进行排序.分析:字符串用ASCII码比较大小,规则是:1.比较首字母的ASCII码大小2.若是前面的字母相同,则比较之后的字母的ASCII码值3.若是 ...

  10. org.apache.commons.lang3包中的isEmpty和isBlank

    主要为了区分一下empty和blank的用法,先看源码: isEmpty public static boolean isEmpty(CharSequence cs) { return cs == n ...