这使得集合的成员变量可以直接被修改,而封装它的类则全然不知,无法介入。
为避免此种情况,我会在类上提供一些修改集合的方法——通常是"添加"和"移除"方法。
这样就可使对集合的修改必须经过类,当程序演化变大时,我依然能轻易找出修改点。
不要让集合的取值函数返回原始集合,这就避免了客户端的意外修改。
| title | content | | —- | —- | | 场景 | 如果你发现子类化只影响类的部分特性,或如果你发现某些特性需要以一种方式来子类化,某些特性则需要以另一种方式子类化,这就意味着你需要分解原来的类。 | | 意义 | | | 定义 | | | 做法 | 决定如何分解类所负的责任。
创建一个新的类,用以表现从旧类中分离出来的责任。
如果旧类剩下的责任与旧类的名称不符,为旧类改名。
构造旧类时创建一个新类的实例,建立"从旧类访问新类"的连接关系。
对于你想搬移的每一个字段,运用【搬移字段】搬移之。每次更改后运行测试。
使用【搬移函数】将必要函数搬移到新类。先搬移较低层函数(也就是"被其他函数调用"多于"调用其他函数"者)。每次更改后运行测试。
检查两个类的接口,去掉不再需要的函数,必要时为函数重新取一个适合新环境的名字。
决定是否公开新的类。如果确实需要,考虑对新类应用【将引用对象改为值对象】使其成为一个值对象。 | | 注意 | |
title | content |
---|---|
场景 | 一个类不再承担足够责任,不再有单独存在的理由(这通常是因为此前的重构动作移走了这个类的责任) |
意义 | |
定义 | 挑选这一"萎缩类"的最频繁用户(也是一个类),以本手法将"萎缩类"塞进另一个类中 |
做法 | 对于待内联类(源类)中的所有public函数,在目标类上创建一个对应的函数,新创建的所有函数应该直接委托至源类。 修改源类public方法的所有引用点,令它们调用目标类对应的委托方法。每次更改后运行测试。 将源类中的函数与数据全部搬移到目标类,每次修改之后进行测试,直到源类变成空壳为止。 删除源类,为它举行一个简单的"丧礼" |
注意 | 有时把相关元素一口气搬移到位更简单,但有时先用内联手法合并各自的上下文,再使用提炼手法再次分离它们会更合适。 |
使用这项重构手法之前,我得确定自己已经尽可能分解了原先的函数。
title | content |
---|---|
场景 | |
意义 | |
定义 | |
做法 | 整理一下待替换的算法,保证它已经被抽取到一个独立的函数中。 先只为这个函数准备测试,以便固定它的行为。 准备好另一个(替换用)算法。 执行静态检查。 运行测试,比对新旧算法的运行结果。如果测试通过,那就大功告成;否则,在后续测试和调试过程中,以旧算法为比较参照标准 |
注意 |