1. 隐藏委托关系
定义:如果某个客户调用了建立了(server object(服务对象)的某个值域基础之上)的函数,那么客户就必须知晓这一委托对象(delegate object)。万一委托关系发生变化,客户也得相应变化。你可以在server端放置一个简单的委托函数(delegating method),将委托关系隐藏起来,从而去除这种依存性。这么一来即便将来发生关系上的变化,变化将被限制在server中,不会涉及客户。
2. 移除中间人
定义:某个类做了过多的简单委托动作,让客户直接调用受托类。在Hide Delegate (隐藏委托关系)的“动机”中,谈到了“封装委托对象”的好处。但是这层封装也是要付出代价的,它的代价是:每当客户要使用受托类的新特性时,你就必须在服务端添加一个简单委托函数。随着委托类的特性(功能)越来越多,这一过程让你痛苦不已。服务类完全变成了“中间人”,此时你就应该让客户直接调用受托类。
3. Demo例子
从两个classes开始,代表[人]的Person和代表[部门]的Department:
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,可以减少耦合(coupling)。为了这一目的,我在Person中建立一个简单的委托函数:
public Person getManager() {
return _department.getManager();
}
现在,我得修改Person的所有客户,让它们改用新函数:
manager = john.getManager();
而移除中间人恰好是该过程的逆操作。
4. 总结
很难说什么程度的隐藏才是合适的。还好,有了Hide Delegate (隐藏委托关系)和Remove Middle Man (移除中间人),你大可不必操心这个问题。因为你可以在系统运行过程中不断进行调整。随着系统的变化,“合适的隐藏程度”这个尺度也相应改变。6个月前恰如其分的封装,现今可能就显得笨拙。重构的意义在于:你永远不必说对不起 ---- 只要把出问题的地方修补好就行了。
by gqzhu