引言
- 在对象的设计过程中,“决定把责任放在哪儿”是一件很重要的事情,如果出现问题则可以运用重构,改变自己原先的设计
- 常常只需使用Move Method(搬移函数)和Move Field(搬移字段)简单的移动对象行为,就可以解决这些问题。如果两个重构手法都有用到,一般会先使用Move Field,再使用Move Method
- 类往往会因为承担过多责任而变得臃肿不堪,这时就可以使用Extract Class(提炼类)将一部分责任分离出去。如果一个类变得太不负责任,则可以使用Inline Class(内联化类)将它融入另一个类中。如果一个类使用了另一个类,可以运用Hide Delegate(隐藏委托关系)将这种关系隐藏起来。有时隐藏了委托类会导致拥有者的接口经常变化,此时需要使用Remove Middle Man(移除中间人)
- 当不能访问某个类的源码,却又想把其他责任移进这个不可修改的类时,可以使用Introduce Foreign Method(引入外加函数)和Introduce Local Extension(引入本地扩展)。其中如果只是想加入一或两个函数,则使用Introduce Foreign Method;如果不止一两个函数,则使用Introduce Local Extension。
1. Move Method(搬移函数)
情景:有个函数与其所驻类之外的另一个类进行更多交流:调用后者,或被后者调用
做法:在该函数最常用引用的类中建立一个有些类似行为的新函数。将旧函数变成一个单纯的委托函数,或者将旧函数完全移除
动机:通过这种手段,可以是系统中的类更简单,这些类最终也将更干净利落地实现系统交付的任务
2. Move Feild(搬移字段)
情景:某个字段被其所驻类之外的另一个类更多地用到
做法:在目标类新建一个字段,修改源字段的所有用户,令它们改用新字段
3. Extract Class(提炼类)
情景:某个类做了应该由两个类做的事
做法:建立一个新类,将相关的字段和函数从旧类搬移到新类
动机:一个类应该是一个清楚的抽象,处理一些明确的责任
4. Inline Class(将类内联化)
情景:某个类没有做太多事情
做法:将这个类的所有特性搬移到另一个类中,然后移除原类
动机:正好与Extract Class相反,如果一个类不再承担足够职责、不再有单独存在的理由
5. Hide Delegate(隐藏委托关系)
情景:客户端通过一个委托类来调用另一个对象
做法:在服务类上建立客户端所需的所有函数,用以隐藏委托关系
动机:如此依赖,一旦发生变化,需要了解这一变化的对象就会比较少——这会使变化比较容易进行
6. Remove Middle Man(移除中间人)
情景:某个类做了过多的简单委托动作
做法:让客户端直接调用受托类
动机:与Hide Delegate正好相反,委托这层封装也是要付出代价的:每当客户端要使用受托类的新特性时,就必须在服务端添加一个简单委托函数,服务类完全变成一个“中间人”。
7. Introduce Foreign Method(引入外加函数)
情景:需要为提供服务的类增加一个函数,但你无法修改这个类。
做法:在客户类中建立一个函数,并以第一参数形式传入一个服务类实例
8. Introduce Local Extension(引入本地扩展)
情景:需要为服务类提供一些额外函数,但无法修改这个类
做法:建立一个新类,使它包含这些额外函数。让这个扩展品成为源类的子类或包装类
动机:如果一直把本该放在扩展类中的代码零散地放置于其他类中,最终只会让其他这些类变得过分复杂,并使得其中函数难以被复用
网友评论