在对象的设计过程中,“
决定把责任放在哪儿”即使不是最重要的事,也是最重要的事之一。常常只需要使用
Move method和move field简单地移动对象行为,就可以解决这些问题。如果这两个手法都需要用到,建议先使用move field再使用move method。
类往往会因为承担过多责任而变得臃肿不堪。这时可以使用Extract Class将一部分责任分离出去。如果一个类变得“不负责任”,就使用Inline Class将它融入另一个类。如果一个类使用了另一个类,运用Hide Delegate将这种关系隐藏起来通常是有帮助的。有时候隐藏委托类会导致拥有者的接口经常变化,此时需要使用Remove middle Man。
4.1 move method(搬移函数)
程序中,有个函数与其所驻类
之外的另一个类进行更多交流,调用后者或被后者调用。就在该函数最常引用的类中建立一个由类似行为的新函数,将旧函数变成一个单纯的委托函数,或是将旧函数完全移除。有时候搬移一组函数比逐个搬移更简单些。
就像图中aMethod()方法老是与Class2交互,那干脆让它们在一起好了。把功能放到Class2中,然后Class1只是直接或间接调用这个方法即可。
4.2 Move field (搬移字段)
程序中某个
字段被其所驻类
之外的另一个类更多地用到,就可以在目标类新建一个字段,修改源字段的所有用户,令它们改用新字段。
在类之间移动状态和行为,是重构过程中必不可少的措施。上述所谓使用可能是通过getter/setter间接进行的。
4.3 Extract Class (提炼类)
程序中某个类做了应该由两个或更多类做的事,就应该建立一个或多个新类,将相关的字段和函数从旧类搬移到新类。
可以结合move field和move method来达到拆分的目的。
拆分原则就是单一职责,一个类只做一件事情。
4.4 Inline Class (将类内联化)
某个类没有做太多事情,就将这个类所有特性搬移到另一个类中,然后移除原类。
Inline Class正好与extract class相反。
需要判断要消除的类的语义是否跟要融入的类的语义接近。
4.5 Hide Delegate (隐藏委托关系)
客户通过一个委托类来调用另一个对象。在服务类上建立客户所需的所有函数,用以隐藏委托关系。
“封装”即使不是对象的最关键特征,也是最关键特征之一。“封装”意味着每个对象都应该尽可能少了解系统的其他部分。如此一来,一旦发生变化,需要了解这一变化的对象就会比较少,这会使变化比较容易进行。
如果某个客户先通过服务对象的字段得到另一个对象,然后调用后者的函数,那么客户就必须知晓这一层委托关系,万一委托关系发生变化,客户也得相应变化。
可以对比4.6的方法,恰当的把握两者的度真的不是那么容易,但我们要知晓,委托和直接调用之间有那么一个“合适的封装和简单的委托”关系。
4.6 Remove Middle Man(移除中间人)
某个类做了
过多的简单委托动作,那就让客户直接调用受委托类,移除中间人。
在讨论Hide Delegate时我们谈到了“封装受委托对象”的好处。但是这层封装也是要付出代价的,每当客户要使用受委托类的新特性时,就必须在服务端添加一个简单委托函数。随着受委托类的特性越来越多,这一过程会让你痛苦不已。
服务类完全变成了一个“中间人”,此时就应该让客户直接调用受托类。
很难说什么程度的隐藏才是合适的。还好,有了Hide Delegate和Remove Middle man,我们就可以在系统运行过程中不断进行调整。随着系统的变化,“合适的隐藏程度”这个尺度也相应改变。
4.7 Introduce foreign Method (引入外加函数)
当需要为提供服务的类增加一个函数,但无法修改这个类时(比如是第三方的类),我们可以在客户类中建立一个函数,并以第一参数形式传入一个服务类实例。
4.8 Introduce Local extension (引入本地扩展)
当需要为服务类提供一些额外函数,但无法修改这个类,可以建立一个新类,使它包含这些额外函数,让这个扩展类称为源类的子类或包装类。
这与Introduce foreign method的区别就是需要扩展的方法比较多。
这也体现了使用组合来代替继承来达到扩展功能的设计思想。
如果只需要扩展一两个函数,就可以使用Introduce foreign method,但如果需要的额外函数超过两个,外加函数就很难控制了,所以就需要将这些函数组织在一起,放到一个恰当地方去。要达到这一目的,两种标准对象技术:子类化(subclassing)和包装(wrapping)是显而易见的办法,我们把这统称为本地扩展。
对比上一篇,如果在一个单独的类中使用extract method等方法已经不能做好内部优化了,那就需要在类之间来做交换或扩展了。
- 大小: 7.9 KB
- 大小: 5.6 KB
- 大小: 10.7 KB
- 大小: 10.9 KB
- 大小: 18 KB
- 大小: 13.9 KB
- 大小: 52.5 KB
- 大小: 8.4 KB
分享到:
相关推荐
### PHP重构系列杂谈:对象间搬移特性的探讨 #### 重构的基本概念 重构(Refactoring)是一种...通过对象间的搬移特性,我们能够更好地处理复杂度,清晰地界定每个类和对象的职责,为软件的长期发展打下坚实的基础。
3. **在对象之间搬移特性**: - **搬移函数**:当一个函数与其所在类的关系不匹配时,可以将其移动到更合适的类中,减少不必要的耦合。 - **搬移字段**:如果某个字段在其他类中被频繁使用,可以将其移动到使用...
章节七 在对象之间搬移特性 章节八 重新组织数据 章节九 简化条件表达式 章节十 简化函数调用 章节十一 处理概括关系 章节十二 大型重构 章节十三 重构,复用与现实 章节十四 重构工具 章节十五 集成
2. **在对象之间搬移特性**:根据对象之间的关系,合理调整成员变量和方法的位置,以提高代码的逻辑一致性。 3. **重新组织数据**:如将全局变量转化为局部变量或封装到类中,以降低代码的耦合度。 4. **简化条件...
65. `M`: `MOVE` - 搬移对象:移动选定的对象到新的位置。 66. `MA`: `MATCHPROP` - 对象特性复制:将一个对象的特性应用到其他对象。 67. `ME`: `MEASURE` - 量测等距布点:在两点之间创建等距的点。 68. `MI`: ...
- 在对象之间搬移特性:调整类或对象的属性和方法,使其更合理地存在于它们所属的地方。 - 重新组织数据:调整数据结构来改善系统的行为。 - 简化条件表达式:清理复杂的条件语句。 - 简化函数调用:使函数调用更...
第7章 在对象之间搬移特性141 7.1 MoveMethod(搬移函数)142 7.2 MoveField(搬移字段)146 7.3 ExtractClass(提炼类)149 7.4 InlineClass(将类内联化)154 7.5 HideDelegate(隐藏“委托关系”)157 7.6 ...
在面向对象编程中,两个类之间可能存在双向关联,即A类包含B类的引用,同时B类也包含A类的引用。这种关联可能导致代码耦合度增加,降低代码的可读性和可维护性。通过将双向关联改为单向,可以减少这种依赖关系,使...
1. **装卸搬运**:货物在仓库或运输过程中进行的搬移操作。 #### 重点问题 1. **装卸搬运的特点**:工作量大、效率低下、容易造成损失等。 2. **装卸搬运的合理化措施**:采用先进的搬运设备、优化操作流程、提高...
第7章 在对象之间搬移特性141 7.1 MoveMethod(搬移函数)142 7.2 MoveField(搬移字段)146 7.3 ExtractClass(提炼类)149 7.4 InlineClass(将类内联化)154 7.5 HideDelegate(隐藏“委托关系”)157 7.6 ...
第7章 在对象之间搬移特性 7.1 MoveMethod(搬移函数)142 7.2 MoveField(搬移字段)146 7.3 ExtractClass(提炼类)149 7.4 InlineClass(将类内联化)154 7.5 HideDelegate(隐藏“委托关系”)157 ...
第7章 在对象之间搬移特性141 7.1 MoveMethod(搬移函数)142 7.2 MoveField(搬移字段)146 7.3 ExtractClass(提炼类)149 7.4 InlineClass(将类内联化)154 7.5 HideDelegate(隐藏“委托关系”)157 7.6 ...
第7章 在对象之间搬移特性 7.1 Move Method(搬移函数) 7.2 Move Field(搬移字段) 7.3 Extract Class(提炼类) 7.4 Inline Class(将类内联化) 7.5 Hide Delegate(隐藏“委托关系”) 7.6 Remove Middle Man(移除...
第7章 在对象之间搬移特性141 7.1 MoveMethod(搬移函数)142 7.2 MoveField(搬移字段)146 7.3 ExtractClass(提炼类)149 7.4 InlineClass(将类内联化)154 7.5 HideDelegate(隐藏“委托关系”)157 7.6 ...
第7章 在对象之间搬移特性 141 7.1 Move Method(搬移函数) 142 7.2 Move Field(搬移字段) 146 7.3 Extract Class(提炼类) 149 7.4 Inline Class(将类内联化) 154 7.5 Hide Delegate(隐藏“委托...