如果你看到用户向一个对象请求另一个对象, 然后再向后者请求另一个对象, 然后再请求另一个对象.......... 这就是消息链条.
实际代码中你看到的可能是一长串getThis()或一长串临时变量. 采取这种方式, 意味着客户代码将与查询工程中的导航结构紧密耦合. 一旦对象间的关系发生了任何变化, 客户端就不得不做出相应修改.
这时候你应该使用 Hide Delegate(隐藏委托关系). 你可以在消息链的不同位置进行这种重构手法. 理论上可以重构消息链条上的任何一个对象, 但是这么做往往会把一系列对象都变成Middle Man. 通常更好的选择是: 先观察消息链条最终得到的对象是用来干什么的, 看看能否以Extract Method(提炼方法) 把使用改对象的代码提炼到一个独立的函数中, 在运用Move Method(移动方法) 把这个函数推入消息链条. 如果这条链上的某个对象有多位客户打算航行此航线的剩余部分, 就加一个函数来做这件事.
有些人把任何消息链都视为坏东西, 我们不这样想. 记住:
具体问题具体分析
Tips:
Hide Delegate(隐藏委托关系)
class Person {
Department _department;
public Department getDepartment(){
return _department;
}
public void setDepartment (Department arg){
_department = arg;
}
}
class Department{
private String _chargeCode;
private Person _manager;
public Department (Person manager){
_manager = manager;
}
public Person getManager{
return _manager;
}
}
如果客户希望知道某人的经历是谁, 他必须先获得Department对象:
manager = john.getDepartment().getManager();
这样的编码就对客户端揭露了Department的工作原理, 于是客户知道:Department用以追踪"经理" 这条信息. 如果对客户端隐藏Department, 可以减少耦合. 为了这一目的, 我在Person中建立一个简单的委托函数:
public Person getManager(){
return _department.getManager();
}
现在,我需要修改Person的所有客户, 让它们改用新函数:
manager = john.getManager();
只要完成了对Department所有函数的委托关系, 并相应修改了Person的所有客户, 我就可以移除Person中的访问函数getDepartment()函数了