分解模块时最重要的标准,也许就是识别出那些模块应该对外界隐藏的小秘密了[Parnas]。数据结构无疑是最常见的一种秘密,我可以用封装记录(162)或封装集合(170)手法来隐藏它们的细节。即便是基本类型的数据,也能通过以对象取代基本类型(174)进行封装——这样做后续所带来的巨大收益通常令人惊喜。另一项经常在重构时挡道的是临时变量,我需要确保它们的计算次序正确,还得保证其他需要它们的地方能获得其值。这里以查询取代临时变量(178)手法可以帮上大忙,特别是在分解一个过长的函数时。

类是为隐藏信息而生的。在第 6 章中,我已经介绍了使用函数组合成类(144)手法来形成类的办法。此外,一般的提炼/内联操作对类也适用,见提炼类(182)和内联类(186)。

除了类的内部细节,使用隐藏委托关系(189)隐藏类之间的关联关系通常也很有帮助。但过多隐藏也会导致冗余的中间接口,此时我就需要它的反向重构——移除中间人(192)。

类与模块已然是施行封装的最大实体了,但小一点的函数对于封装实现细节也有所裨益。有时候,我可能需要将一个算法完全替换掉,这时我可以用提炼函数(106)将算法包装到函数中,然后使用替换算法(195)。

7.1 封装记录(Encapsulate Record)

7.2 封装集合(Encapsulate Collection)

7.3 以对象取代基本类型(Replace Primitive with Object)

7.4 以查询取代临时变量(Replace Temp with Query)

7.5 提炼类(Extract Class)

7.6 内联类(Inline Class)

7.7 隐藏委托关系(Hide Delegate)

7.8 移除中间人(Remove Middle Man)

7.9 替换算法(Substitute Algorithm)