《重构-改善既有代码的设计》系列读书笔记(八、大型重构和个人总结)

大型重构

不要被名字吓到。。。

Tease Apart Inheritance(梳理并分解继承关系)

某个继承体系同时承担两项责任

动机
  • 混乱的继承体系是一个严重的问题,它会导致重复代码,会使修改变得困难。
  • 如果继承体系中的某一特定层级上的所有类,其子类名称都以相同的形容词开始,那么这个体系很可能承担着两项不同的责任。
做法
  • before

  • after

Convert Procedural Design to Objects(将过程化设计转化为对象设计)

你手上有一些传统过程化风格的代码

动机
  • 在面向对象语言中,应该尽量少的使用过程化的代码,多用对象。
做法
  • 将数据记录变成对象,将大块的行为分割小块,并将行为移入相关对象之中。

Separate Domain from Presentation(将领域和表述/显示分离)

某些GUI类之中包含了数据处理逻辑

动机
  • MVC模式。。。
  • M 还是 VM ?这是一个问题。
做法
  • 将显示逻辑和数据处理逻辑分离。。。

Extract Hierarchy(提炼继承体系)

你有某个类做了太多工作,其中一部分工作是以大量条件表达式完成的。

动机
  • 当一个简单的类在不断迭代之后,可能产生一系列不同的行为,这些行为的执行依赖于各种条件和标记,日积月累,这个类就完全一团糟了。
  • 只有这些条件和标记在整个类的生命周期内保持不变时,本重构手法才适用。
  • Extract Hierarchy是一项大型重构,可能需要花费大量的时间和精力,先易后难,循序渐进。
做法
  • 将各种需要条件判断的地方提炼为一个新的子类,直到将超类改为抽象类为止。

总结

总结以上各种重构手段,我们不难发现,重构的最终目主要有以下两点:

消除重复代码

我们所以要提炼函数,提炼类,消除临时变量,重新组织数据,内联函数和类,大部分操作都是在消除重复的代码。

重复代码的危害是显而易见的,它除了增加你的整体代码量,使你的逻辑变得更复杂外,也阻碍着他人阅读和理解你的代码,并且大大增加了代码的维护成本。所以说消除重复代码,不止可以大大降低代码维护成本,还能减少整体代码量,提高代码的可读性,可以说是一举多得。

然而在实际的开发过程中,往往还是会出现很多的重复代码,这种代码主要出现在相似的功能模块之间,而且后来者重复前人代码的比例会更大一些。可能由于懒得,开发时间,个人素质等各种原因,最终导致项目中出现大量重复代码。

要解决重复代码的问题,我个人觉得首先需要提高开发者的个人素质,一个对自己代码严格要求的开发者在编码过程中会时刻提醒自己减少重复。其次,团队开发中代码review是必要的,而且应该严格执行,不能因为个人惰性,面子问题或者时间不够这些主观原因而不做或者打折扣。你做或者不做,代码都在那里,不增不减。

梳理代码之间的关系(类,函数等)

对代码之间关系的梳理,是能够大大改善代码的另外一个手段。程序本质上就是由各种代码串联起来的一个软体,代码间的关系决定了软件的所有行为。这些关系主要包括类的关系,函数的关系,条件语句的关系和数据的关系。

计算机科学和土木工程,电子信息,机械等专业都被归于工科,说明他们之间是有一些共性存在的。我们可以参考土木工程中一个项目的整体流程,然后和计算机软件项目来一个大致的对比。土木工程师在开始一个项目时,会花费大量的时间去做方案设计,中间可能需要经过多次改版,最终方案形成后才会开始施工,而且必须是严格按照设计方案来施工,不然后面的验收可能就会不通过。反观软件工程师的开发流程,则简单很多,前期及时有方案设计,也不会事无巨细,可能几个主要的模块确定后,就可以开始编码。

土木和计算机软件的主要差别就体现在“软”字上,土木的设计方案如果出问题,并且在初期并没有被发现话,对项目整体影响会很大,而软件开发中对代码的修改是随时的,并不会产生什么大的影响。正是基于软件的这种特殊属性,也就出现了大量因为设计不良,甚至根本谈不上设计的代码,而这种不经设计的代码,正是导致代码之间关系混乱的元凶。

和代码重复不同的是,良好的代码关系并不是开发者多注意就可以形成的。需要大量的学习和实践才能有一些心得,而将这些心得运用到项目中又需要一些时间成本,所以总体上讲好的代码关系在实际开发过程中不可能尽善尽美,开发者能做的就是尽自己最大的努力去设计出合理的代码关系,然后在不断的重构中去进一步完善。这就要求我们对设计模式学习和实践的脚步不能停止。