在 “消除switch/case语句,不破坏代码的封闭性,使程序结构更符合面向对象思想(一)”中,我们曾讨论过维护一个消息管理器来记录不同消息和它对应的消息处理类。

但是,这种实现方式存在一个问题,考虑下:如果我们项目的业务逻辑很复杂,比如需要处理100多个消息类型,那我们就需要实现100多个消息处理类,维护这么多个消息处理类是相当麻烦的。怎么办?

思路:我们只能采取一种折中的方法,即把所有的消息处理类变成消息处理函数,然后把他们放到一个类中(All In One)统一管理,新添加一个消息,就要在该类中添加相应的处理函数。这种方法不太符合面向对象的思想,但从实际的变成角度来看,这样做可以大大减少类的数量,更容易维护。

好了,开始讲具体的实现:

1、消息处理器现在记录的是:消息类型ID 和 处理这个消息的成员函数的地址

2、成员函数必须要有它自己的对象来调用,所以我们还要保存一个指针用来指向该All In One的消息处理类

1、先来看看新版本中,消息管理器的实现:

typedef CStatus (CMessageProcessor:: *MsgProCallBackFunc)(CMessage * pMsg);  //消息处理的成员函数
CMessageProcessorAllInOne * pMsgPro;  //消息处理成员函数的调用者
std::map<unsigned long MsgTypeID, MsgProCallBackFunc> MsgManagerTable;  //消息管理器

2、消息的注册:在消除switch/case语句...(一)中,我曾经说过,消息分配这整个业务逻辑是建立在一个基于消息循环机制的线程通信框架上的。

我们暂且给这框架的主要实现类命名为:MessageLoopManager,OK,现在开始讲消息注册的实现

class CMessageProcessorAllInOne
{
virtual CMessageProceesorAllInOne(CMessageLoopManager * pMsgLoopMgr, void * pContext)
{pMsgLoopMgr->Register(MSG_B,(MsgProCallBackFunc)&(CMessageProcessorAllInOne::On_MsgB));
pMsgLoopMgr->Register(MSG_B,(MsgProCallBackFunc)&(CMessageProcessorAllInOne::On_MsgC));
}CStatus On_MsgB(CMessage * pMsg){... ...}CStatus On_MsgC(CMessage * pMsg){... ...}... ...};

3、消息的分配

DispatchMessage(CMessage * pMsg)
{
std::map<...>::iterator it;
it = MsgManagerTable.find(pMsg->MsgTypeID);
MsgProCallBackFunc * pFunc = it->second;
return (pMsgPro->*pFunc)(pMsg);
}

比较:

消除switch/case语句,不破坏代码的封闭性,使程序结构更符合面向对象思想(一)

消除switch/case语句,不破坏代码的封闭性,使程序结构更符合面向对象思想(二)

(一)更符合面向对象思想,且真正做到了不破坏代码的封闭性,每次想要添加一个新的消息,可以直接派生出一个新的消息类。但如本问所述,当消息太多时,就会导致需要创建的消息类太多,增加了维护成本。而在本文所讨论的方法中,又破坏了代码封闭性。这实际上是一种悖论,正所谓甘蔗不能两头甜,

所以具体使用(一)还是(二)我们要根据项目中具体情况而定,如果你用到的消息类型不多,你完全可以选用方法(一)来实现。反之ba la ba la.....

消除switch/case语句,不破坏代码的封闭性,使程序结构更符合面向对象思想(二)相关推荐

  1. 工厂模式之消除switch/case语句

    2019独角兽企业重金招聘Python工程师标准>>> 我们在平时的编码中,我们经常会遇到这样的情况: 使用过多的switch/case 或者 if else 语句,非常不爽,也违背 ...

  2. python中有没有switch_Python为什么没有switch/case语句?

    与我之前使用的所有语言都不同,Python没有switch/case语句.为了达到这种分支语句的效果,一般方法是使用字典映射: def numbers_to_strings(argument): sw ...

  3. java break在switch_java中switch case语句需要加入break的原因解析

    java中switch case语句需要加入break的原因解析 java 中使用switch case语句需要加入break 做了具体的实例分析,及编译源码,在源码中分析应该如何使用,大家可以参考下 ...

  4. python中case的用法_python中Switch/Case实现的示例代码

    python 的 python中Switch/Case实现的示例代码 学习Python过程中,发现没有switch-case,过去写C习惯用Switch/Case语句,官方文档说通过if-elif实现 ...

  5. python中没有switch-case_Python为什么没有switch/case语句?

    与我之前使用的所有语言都不同,Python没有switch/case语句.为了达到这种分支语句的效果,一般方法是使用字典映射: def numbers_to_strings(argument): sw ...

  6. c语言case怎么输入字母,如何使用switch case语句将字母转换为数字

    我正在制作黑色插口游戏,并且需要使用switch case语句将A转换为11,将T,Q,J和K转换为10,但是我不确定如何执行代码.有人会帮助我解决这个问题吗?如何使用switch case语句将字母 ...

  7. C语言case字句有什么作用,switch case 语句的使用规则

    [规则1-21]按字母或数字顺序排列各条case语句. 如果所有的case语句没有明显的重要性差别,那就按A-B-C或1-2-3等顺序排列case 语句.这样做的话,你可以很容易的找到某条case语句 ...

  8. php case语句吗,【PHP公开课|关于PHP switch case语句,你知道怎么用吗,这个例子你一定要来看看】- 环球网校...

    [摘要]PHP作为一种超文本预处理器,已经成为了我们常用的网站编程语言,并且结合了C语言,Java等我们常见的编程语言,所以,有很多web开发领域的新人都看中了他的使用广泛性,有很多人都想了解php的 ...

  9. java case switch面试_Java基础篇——Java中switch case语句用法及注意事项面试题9期

    本文主要说一说关于switch case语句用法及注意事项,应对面试官的提问.希望可以帮助那些对switch存在错误和各种细节问题的"码友". switch-case注意事项 sw ...

最新文章

  1. .htaccess的重写规则
  2. 记录这两日悲哀的血泪史,以便后来人能绕行
  3. 4.QPixmap,QTransform,绘图函数的使用
  4. 为DedeCms的RSS生成绝对地址
  5. LeetCode——Backtracking
  6. crontab 每分钟一次_Celery实现定时任务crontab
  7. 如何在php中写内容,请问如何在内容模板中写标题和内容呢
  8. python将一组数据转化为列表_Pandas将列表(List)转换为数据框(Dataframe)
  9. poj 2922 Honeymoon Hike
  10. udp wpf 权限_基于WPF开发局域网聊天工具,在用udp做上线功能时遇到的有关问题...
  11. PHP爬取搜狗微信文章内容
  12. Flutter时间日期格式化等操作(一个月的最后一天日期,时间段内所有日期...)
  13. BUCK电路、BOOST电路,为其设计电压电流双闭环调节器,实现系统阶跃响应
  14. 利用代码自动逛店铺拿喵币
  15. python中文分句_中文文本分句
  16. 【Vegas原创】word图片隐藏在文字里了的终极解决办法
  17. 小学计算机输入法主题教研设计,《拼音输入法》教学设计.doc
  18. LaTex 解决目录红框问题
  19. 润科通用 Java开发工程师 面试
  20. SpringBoot2.0.3+Mybatis+Mysql+druid实现读写分离+事务+切换数据源失败

热门文章

  1. eclipse plugin
  2. 综述天分、标网、矢网、扫频仪的异同
  3. vmware虚拟机安装win7_vmware虚拟机中安装mac Catalina10.15
  4. 免费下载学术文献的网站,好用!
  5. 网络聊天室(linux,java,Android)
  6. win10如何调整计算机时间同步,win10系统调整设置时间同步的频率的操作方法
  7. Golang 和 lua 相遇会擦出什么火花?
  8. windows平台查看CPU支持的指令集 代码:__cpuid,__cpuidex
  9. 1.12 W10的CMD常用命令,以及CMD装逼操作
  10. APEX包管理器简述(二)