《重构--改善既有代码的设计》读书笔记

来源:互联网 发布:woc网络用语 编辑:程序博客网 时间:2024/05/17 00:19

masuo推荐我的一本书。这本书写的通俗易懂,里面的很多技巧看起来很普通却很重要。

看完这本书之后我最大的收获是认识到:重构也是设计的一部分。不再会为初期设计的缺陷感到苦恼。我前面的经验是:初期设计得越完美,后边越苦恼!


何谓重构:使用一系列重构手法对软件内部结构进行调整,目的是在不改变程序功能的前提下,提高其可理解性,降低代码的修改和维护成本。

为何重构:1 改进软件设计   2 使代码更容易理解   3 帮助找BUG(这个理由有点偏?)  4 提高开发效率

何时重构:代码有坏味道的时候


以下内容格式为:

编号 代码的坏味道 [解释]

解决方法


BEGIN

1 重复的代码

<1>若干个函数中有相同的一部分代码,那么把相同的代码提炼为一个新的函数,在把重复的代码段替换为新函数的调用。(Extract Method)

<2>另一种常见的情况是"若干个互为兄弟的子类含有相同的表达"。这时需要分别对这若干类使用Extract Method,把提炼出来的代码推入父类(Pull Up Method)

<3>如果兄弟类之间的两个函数以相同顺序执行大致相近的操作,但是各种操作不完全相同。这时可以将执行操作的序列移动到基类,并借助多态保证各操作仍得以保持差异性。这样的函数被称为Template Method(模板函数)【GOF】(Form Template Method)


2 过长的函数

<1>大多数时候用Extract Method方法提炼出新的子函数

<2>一个比较重量级的方法:Replace Method with Method Object(以函数对象替换函数)。那么原函数中的局部变量成了对象的字段,然后将函数逻辑分解为多个小函数


3 过大的类

<1>Extract Class:一个类做了两个类应该做的事,把它分成两个类

<2>Extract Subclass:类中的特性只能被某些实例用到。新建一个类,将那一部分特性放到它的子类。


4 过长的参数列表

<1>Replace Parameter with Method:对象调用某个成员函数并将结果作为参数传给另一个函数,而接受参数的函数也能调用前一个函数。去掉该参数项在函数体中直接获取。(例外,这个对象接口带有参数,并且这个函数不能获取这些参数)。

<2>Preserve Whole Object:把参数列表中来自同一对象的参数用对象替换掉。

<3>Introduce Parameter Object:创造一个参数对象,以替换过长的参数列表。


5 发散式变化(Divergent Change)  一个类在加入某个新功能时,其中若干个成员函数都需要被改动。在加入另一个新功能时,也需要改变类中若干个方法。

此时应该把类分成两个,这样每个对象就可以只因为一种变化尔需要修改。(Extract Class)


6 散弹式修改(Shotgun Surgery) 与上一点相反。每遇到一种变化,你都需要在许多不同的类里做出许多小的修改。如果需要修改的代码散布四处,并且容易遗漏一些修改。

<1>用Move Method & Move Field把所有需要修改的代码放进同一个类。如果没有这样的类就创造一个。

<2>用Inline Class将一系列相关行为放进同一个类。Inline Class:与Extract Class 相反,把一个没有存在必要的类的内容移动到另一个类中,并把原类删除。


7 依恋情节(Feature Envy) 如果类中某成员函数对其他类的兴趣高于自己所在的类,此时它或许应该被移动到另一个类去。

用到的方法当然是Move Method,如果函数中只有一部分有依恋情节,那么先Extract Method然后Move Method。


8 数据泥团(Data Clumps) 相同的若干项数据,出现在不同的地方(类的成员变量、函数的参数列表等等)。这些绑在一起出现的数据应该有属于它们自己的对象。


9 基本类型偏执(Primitive Obsession)  很多人不愿意在小任务上运用小对象,而更偏向于使用语言内置的基本类型。作者认为可以Replace Data Value with Object。


10 Switch Statements

11 平行继承体系(Parallel Inheritance Hierarchies) 当你为某个累增加一个子类时,也必须为另一个累相应增加一个子类。

12 Lazy Class

13 Speculative Generality  典型过度设计的特征。

14 令人迷惑的暂时字段(Temporary Field) 这里所说的字段是指:一个类的某成员变量仅仅为某种特定情况而设。这时应该把这种字段和与其相关的逻辑移动到一个新类中。

15 过度耦合的消息链(Message Chains) 用户向对象请求另一个对象,然后再请求另一个对象......这意味着,客户代码与对象间的关系紧密耦合。对象间的关系一旦发生变化,客户代码不得不做出相应的修改。

16 过多的中间人   也就是过度运用委托。

17 狎昵关系(Inappropriate Intimacy)  两个类过于亲密,花太多时间去探究彼此的private成分。

18 异曲同工的类(Alternative Classes width Different Interfaces)

19 不完美的类库(Incomplete Library Class)

20 数据类(Data Class) 数据类是指拥有一些字段,以及访问它们的接口,除此之外一无长物。

21 被拒绝的遗赐(Refused Bequest)  基类?(超类)中的函数和数据不没有被完全继承。

22 过多的注释  漂亮的代码本身就是很好的注释。太多的注释往往是代码糟糕的标志。

END


note:读完一本书真的非常快。但是要做笔记备忘的话真得花较多时间。记得不完整的部分后边有空了再补上。

原创粉丝点击