如果你看到用戶向一個對象請求另一個對象, 然后再向后者請求另一個對象, 然后再請求另一個對象.......... 這就是消息鏈條.
實際代碼中你看到的可能是一長串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()函數了