代码重构:过长的消息链(Message Chains)

举报
孙小北 发表于 2022/04/29 23:43:35 2022/04/29
【摘要】 什么是过长的消息链(Message Chains)定义:如果你看到用户向一个对象请求另一个对象,然后再向后者请求另一个对象,然后再请求另一个对象……这就是消息链。在实际代码中你看到的可能是一长串取值函数或一长串临时变量。影响:客户端代码将与查找过程中的调用结构紧密耦合。一旦对象间的关系发生任何变化,客户端就不得不做出相应修改。改进目标:针对过长消息链,可以用这时候应该使用隐藏委托关系,把调...

什么是过长的消息链(Message Chains)

  • 定义:如果你看到用户向一个对象请求另一个对象,然后再向后者请求另一个对象,然后再请求另一个对象……这就是消息链。在实际代码中你看到的可能是一长串取值函数或一长串临时变量。
  • 影响:客户端代码将与查找过程中的调用结构紧密耦合。一旦对象间的关系发生任何变化,客户端就不得不做出相应修改。
  • 改进目标:针对过长消息链,可以用这时候应该使用隐藏委托关系,把调用链这种耦合关系放在中间人中。
  • 方法:
    1.观察清楚消息链的调用业务逻辑。
    2.通过提炼函数把所有相同调用放在一个函数中
    3.搬移函数到对应的中间人类中(新增或者使用以前的类)
    4.替换这个函数到之前调用链。隐藏委托关系
  • 注:有些人把任何函数链都视为坏东西,我们不这样想。我们的冷静镇定是出了名的,起码在这件事上是这样的。

案例1

代码背景

  • 一个客户端期望能访问一个人的部门地址的门牌号和具体地址。
  • 普通实现如果采用消息链调用的方式,调用方式为:person.getDepartment().getAddress().getStreet().getStreetName()

症状/问题

  • InformationClient会知道整个Person依赖关系和组织实现,形成耦合关系。
  • 消息链太长导致代码不易重构,不易修改。如果Person内部依赖关系或数据结构进行调整、重构,那么外部调用链同时被修改。

重构方法/目标

  • InformationClient直接访问Person就能得出Street对象(这里是部门对象)
  • 人、部门、地址、街道整个依赖关系对client透明。
  • 后面如果发生变化和重构,外部无感知。

image-20220429193725642.png

改进方式

  • 改进前:Client感知到了整个内部逻辑,形成依赖
  • 改进后:隐藏了内部数据结构依赖关系,使用Person作为“中间人”,为Client屏蔽委托关系

image-20220429193757081.png

引申知识

  • 过长的消息链到底是在说什么?到底有什么问题,为什么需要修改?深模块VS 浅模块

深模块:

  • 最好的模块提供了强大的功能,又有着简单的接口。术语“深”可以用于描述这种模块。
  • 可以从成本与收益的角度思考模块深度。模块提供的收益是它的功能。
  • 模块的成本(从系统复杂度的角度考虑)是它的接口。接口代表了模块施加给系统其余部分的复杂度。接口越小而简单,它引入的复杂度就越少。
  • 好的模块就是那些成本低收益高的模块。

浅模块:

  • 就是模块内部暴露给外部调用或者使用,内部没有隐藏太多的逻辑,外部都能感知到内部的具体逻辑或者结构组织,或调用关系。
  • 上述修改前的代码就是一个典型的浅模块的暴露和外部调用,外部是可以感知到内部实现的,是一种典型的不好的代码设计。

最后:Classitis

  • 当今,深模块的价值并没有被广为接受。一般常识是类需要小,而不是深。学生们被告知:类设计中最重要的事情是把大类拆分成更小的类。
  • 相似的建议还包括:“要把方法行数大于N的方法分成多个方法”,有时候N甚至只有10这么小。这会导致大量的浅模块,增加系统的总复杂度。
  • 极端的“类应该小”的做法是一种综合症的表现,这种症状可以被称为Classitis。
  • 它源于一种错误思维:“类是好的,所以越多类越好”。
  • 这种思想最终会导致系统层面积累了巨大的复杂度,程序风格也会变得啰嗦。

总结

image-20220429193933174.png

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。