Java Tip: 用Reflection實現Visitor模式
概述
Visitor模式的常用之處在於,它將對象集合的結構和對集合所執行的操作分離開來。例如,它可以將一個編譯器中的分析邏輯和代碼生成邏輯分離開來。有了這樣的分離,想使用不同的代碼生成器就會很容易。更大的好處還有,其它一些公用程序,如lint,可以在使用分析邏輯的同時免受代碼生成邏輯之累。不幸的是,向集合中增加新的對象往往需要修改已經寫好的Visitor類。本文提出了一種在Java中實現Visitor模式的更靈活的方法:使用Reflection(反射)。
-------------------------------------------------------------
集合(Collection)普遍應用於面向對象編程中,但它也經常引發一些和代碼有關的疑問。例如,"如果一個集合存在不同的對象,該如何對它執行操作?"
一種方法是,對集合中的每個元素進行迭代,然後基於所在的類,對每個元素分別執行對應的操作。這會很難辦,特別是,如果你不知道集合中有什麼類型的對象。例如,假設想打印集合中的元素,你可以寫出如下的一個方法(method):
public void messyPrintCollection(Collection collection) {
Iterator iterator = collection.iterator()
while (iterator.hasNext())
System.out.println(iterator.next().toString())
}
這看起來夠簡單的了。它只不過調用了Object.toString()方法,然後打印出對象,對嗎?但如果有一組哈希表怎麼辦?事情就會開始變得復雜起來。你必須檢查從集合中返回的對象的類型:
public void messyPrintCollection(Collection collection) {
Iterator iterator = collection.iterator()
while (iterator.hasNext()) {
Object o = iterator.next();
if (o instanceof Collection)
messyPrintCollection((Collection)o);
else
System.out.println(o.toString());
}
}
不錯,現在已經解決了嵌套集合的問題,但它需要對象返回String,如果有其它不返回String的對象存在怎麼辦?如果想在String對象前後添加引號以及在Float後添加f又該怎麼辦?代碼還是越來越復雜: