我做得很好主人訪問者模式。 但是,我想知道一些事情。實現使用實例的訪問者
使用訪問者模式最重要的動機是在客戶端添加涉及特定數據模型的邏輯,而不需要檢查真實的數據對象類型。用於求解的技術被稱爲雙調度(Double-Dispatching)。
所以,這裏的數據模型的代碼片段實現的accept()
方法:
public class Ferrari extends Car {
//......
@Override
public void accept(Visitor v){
v.visit(this);
}
}
而且這裏PrintCarVisitor
實現Visitor
接口:
public class PrintCarVisitor implements Visitor {
//...
@Override
public void visit(Ferrari c){
System.out.println("Ferrari");
}
}
因此,沒有if/else
系列和instanceof
系列需要。
任何客戶端將是:
Visitor visitor = new PrintCarVisitor();
car.accept(visitor); //no need to know the exact Car's type
然而,由於遊客不守開/閉原則(因爲新的數據模型導致通過增加自己的visit
方法打破類),爲什麼我們打擾雙重派遣?
難道我們不能僅僅在訪客實現中隔離if/else
系列。
有了這個假設的替代,這部分代碼就會消失:
public class Ferrari extends Car {
//This method is not needed anymore with this alternative
@Override
public void accept(Visitor v){
v.visit(this);
}
}
PrintCarVisitor
將是:
public class PrintCarVisitor {
public void visit(Car c){
if(c instanceof Ferrari){
System.out.println("Ferrari");
}
}
}
有了這個選擇,每一個來電者仍然會處理這樣的數據模型抽象:
new PrintCarVisitor().visit(car); //no need to know the exact data type in client side
先驗,第二種方法非常好,因爲它不涉及實現純訪問者模式期間生成的所有樣板文件。
我想像這種方法有兩個缺點:
1)有沒有保證(如Visitor
接口強行),任何訪問者使用對應於當前處理的Car
的方法處置。
2)BoilerPlate代碼在遊客實現類中仍然較重,其中instanceof
和casting
系列爲。
他們是否存在其他任何缺陷,解釋爲什麼訪客模式必須使用Double Dispatching,因此不能簡單地在類中隔離instanceof
系列(例如靜態Factory
)?
我喜歡你的答案。我完全同意'instanceof'不是OO,所以應該避免。我的問題不是爲了瞭解最佳做法,而是強烈理解爲什麼雙重調度是訪客模式的唯一選擇。謝謝;) – Mik378