本文介紹了常見面向對象語言(Java,C#等)OverLoad對于運行時執行的方法邦定的局限,并且如何通過Double Dispatch來實現運行時行為邦定。
1 根據對象來選擇行為問題
public interface Event {
}
public class BlueEvent implements Event {
}
public class RedEvent implements Event {
}
public class Handler {
public void handle(Event event){
System.out.println("It is event");
}
public void handle(RedEvent event){
System.out.println("It is RedEvent");
}
public void handle(BlueEvent event){
System.out.println("It is BlueEvent");
}
}
public class Main {
public static void main(String[] args) {
Event evt=new BlueEvent();
new Handler().handle(evt);
}
}
你認為運行結果是什么呢?
結果:It is event
是不是有點出乎意料,不是It is BlueEvent,這是應為Overload并不支持在運行時根據參數的運行時類型來幫定方法,所以要執行哪個方法是在編譯時就選定了的。
2 Double Dispatch Pattern
由于Java,C++及C#都具有上述局限,通常我們只能通過Switch或if結構來實現,當然這種實現方式既不優雅而且影響代碼的可維護性。
通過以下的Double Dispatch Pattern便可以優雅的實現。
public interface Event {
public void injectHandler(EventHandler v);
}
public class BlueEvent implements Event {
public void injectHandler(EventHandler v) {
v.handle(this);
}
}
public class RedEvent implements Event {
public void injectHandler(EventHandler v) {
v.handle(this);
}
}
public class EventHandler {
public void handle(BlueEvent e){
System.out.println("It is BlueEvent");
}
public void handle(RedEvent e){
System.out.println("It is RedEvent");
}
}
public class Main {
public static void main(String[] args) {
Event evt=new BlueEvent();
evt.injectHandler(new EventHandler());
}
}
其實設計模式(GoF)中的Visitor模式就是Double Dispatch的一種應用。
蔡超
HP
軟件架構師
軟件架構顧問
SCEA,SCBCD,MCSD
IBM Certified Solution Designer for
OOA&D vUML2
Chaocai2001@yahoo.com.cn,chao.cai@hp.com