《重构_改善既有代码的设计》摘要(下)
第十章 简化函数调用
1、Rename Method 函数改名:函数的名称未能揭示函数的用途。修改函数名称。
给函数命名的一个办法:首先考虑给函数写上怎样的注释,然后将注释转换成函数名。
2、Add Parameter 添加参数:某个函数需要从调用端得到更多信息。为此函数添加一个对象参数,让该对象带进函数所需信息。
先要确定现有参数能否满足要求,如果不满足,为什么?要防止过长的参数队列。
3、Remove Parameter 移除参数:函数本体不再需要某个参数。将该参数去除。
4、Separate Query from Modifier 将查询函数和修改函数分离:某个函数既返回对象状态值,又修改对象状态。
建立两个不同的函数,其中一个负责查询,另一个负责修改。
5、Parameterize Method 令函数携带参数:若干函数做了类似的工作,但在函数本体中却包含了不同的值。建立单一函数,以参数表达那些不同的值。
6、Replace Parameter with Explicit Methods 以明确函数取代参数:你有一个函数,其中完全取决于参数值而采取不同行为。
针对该参数的每个可能值,建立一个独立函数。
7、Preserve Whole Object 保持对象完整:你从某个对象中取出若干值,将它们作为某次函数调用时的参数。改为传递整个对象。
8、Replace Parameter with Methods 以函数取代参数:对象调用某个函数,并将所得结果作为参数,传递给另一个函数。
而接受该参数的函数本身也能调用前一函数。让参数接受者去除该项参数,并直接调用前一个函数。
9、Introduce Parameter Object 引入参数对象:某些参数总是很自然地同时出现。以一个对象取代这些参数。
10、Remove Setting Method 移除设值函数:类中的某个字段应该在对象创建时被设值,然后就不再改变。去掉该字段的所有设值函数。
11、Hide Method 隐藏函数:有一个函数,从来没有被其他任何类用到。将这个函数修改为private。
12、Replace Constructor with Factory Method 以工厂函数取代构造函数:你希望在创建对象时不仅仅是做简单的建构动作。
将构造函数替换为工厂函数。
13、Encapsulate Downcast 封装向下转型:某个函数返回的对象,需要由函数调用者执行向下转型。将向下转型动作移到函数中。
14、Replace Error Code with Exception 以异常取代错误码:某个函数返回一个特定的代码,用以表示某种错误情况。改用异常。
15、Replace Exception with Test 以测试取代异常:面对一个调用者可以预先检查的条件,你抛出了一个异常。
修改调用者,使它在调用函数之前先做检查。
第十一章 处理概括关系
1、Pull Up Field 字段上移:两个子类拥有相同的字段。将该字段移植超类。所谓相同是指使用方式类似。
2、Pull Up Method 函数上移:有些函数,在各个子类中产生完全相同的效果。将该函数移植超类。
3、Pull Up Constructor Body 构造函数本体上移:你在各个子类中拥有一些构造函数,它们的本体几乎完全一致。
在超类中新建一个构造函数,并在子类构造函数中调用它。
4、Push Down Method 函数下移:超类中的某个函数只与部分(而非全部)子类有关。将这个函数移到相关的那些子类去。
5、Push Down Field 字段下移:超类中的某个字段只被部分(而非全部)子类用到。将这个字段移到需要它的那些子类去。
6、Extract Subclass 提炼子类:类中的某些特性只被某些(而非全部)实例用到。新建一个子类,将上面所说的那一部分特性移到子类中。
7、Extract Superclass 提炼超类:两个类有相似特性。为这两个类建立一个超类,将相同特性移至超类。
8、Extract Interface 提炼接口:若干客户使用类接口中的同一子集,或者两个类的接口有部分相同。将相同的子集提炼到一个独立接口中。
9、Collapse hierarchy 折叠继承体系:超类和子类之间无太大区别。将它们何为一体。
10、Form Template Method 塑造模板函数:你有一些子类,其中相应的某些函数以相同顺序执行类似的操作,但各个操作的细节上有所不同。
将这些操作分别放进独立函数中,并保持它们有相同的签名,于是原函数也就变得相同了,然后将原函数上移至超类。
11、Replace Inheritance with Delegation 以委托取代继承:某个子类只使用超类的部分接口,或者根本不需要继承而来的数据。
在子类新建一个字段用以保存超类,调整子类函数,令它改而委托超类;然后去掉两者之间的继承关系。
12、Replace Delegation with Inheritance 以继承取代委托:你在两个类之间使用委托关系,并经常为整个接口编写许多极简单的委托函数。
让委托类继承受托类。
第十二章 大型重构
1、进行大型重构时,有必要为团队成员建立共识,整个团队都必须意识到我们正在重构,每个人都应该相应地安排自己的行动。
2、Tease Apart Inheritance 梳理并分解继承体系:某个继承体系同时承担两项责任。建立两个继承体系,并通过委托关系让其中一个可以调用另一个。
3、Conver Procedural Design to Objects 将过程化设计转化为对象设计:你手上有一些传统过程化风格的代码。
将数据记录变成对象,将大块的行分成小块,并将行为移入相关对象之中。
4、Separate Domain from Presentation 将领域和表述/显示分离:某些GUI类之中包含了领域逻辑。将领域逻辑分离出来,为它们建立独立的领域类。
5、Extract Hierarchy 提炼继承体系:你有某个类做了太多工作,其中一部分是以大量条件表达式完成的。
建立继承体系,以一个子类表示一种特殊情况。
第十三章 重构,复用与现实
1、重构需要意识、决心、技术、可能还需要一个好的团队。
2、如何让领导、用户认可重构?需要描述重构在短期内产生的利益。
3、降低重构带来的开销:比如融入日常开发。时间会证明重构的好处。
4、安全地进行重构:
1)充分利用编译器、测试套件、代码评审等这些工具提供的代码检查验证功能。
2)专门的重构工具。
3)将大的重构分解成小的重构,并保证每个小的重构的安全性。
5、从重构到软件复用和技术传播。一些原则:
1)软件复用和技术传播都需要软件开发者具有一定的新思想,且本身就必须十分关心这些技术。
2)技术的接纳可以描述成一条钟形曲线:前段包括先行者和早期接受者,中期包括急剧增加的人群(早期消费者和晚期消费者),后段则是
那些行动迟缓者。先行者主要关注新技术,早期/晚期消费者主要关系成熟度、成本、支持等。如果要让你的技术能被所有人接受,
解这些差异非常重要。因为不同的人群关注的方面不同。
第十四章 重构工具
1、没有自动化的重构工具是大多数人不愿重构的原因之一。手动重构花费过大。
2、自动化重构工具应该具有的技术标准:
1)借助语义分析来对每个单词建立程序数据库。
2)解析树,用来表示函数结构。
3)准确性。
3、自动化重构工具应该具有的实用标准:
1)速度
2)撤销
3)与其它工具集成
第十五章 总结
1、怎么判断自己对重构是否“得道”?当你可以自信地停止重构的时候。可能是重构的目标全部实现,也可能是只实现了一部分,更有可能是一切又回到了起点。
这个过程中,你会学习到很多。重构没有终点,没有截止日期,需要的是持之以恒。
2、如何学习重构:
1)挑选一个目标
2)没把握就停下来
3)学习原路返回
4)二重奏