2012-08-29 67 views
2

我對訪問者模式有疑問!想象一下,我有數據結構類,內部它有一個與Class2的關係。 Class2具有約10個類的特定類層次結構。Java的訪問者模式

我需要查看Class1實例的列表並根據Class2的類型爲Visitor.visit(Class1)調度請求。我不能在class2中使用迭代,因爲我需要class1上下文中的變量。

現在,我想講講調度員誰接受Class1的對象,那麼這個類是檢查類class2類型和調用的東西的基礎上

visitor.visitClass2Type1(Class1的對象)

但在這種情況下,我放棄了訪客模式的相同簽名...

另一個問題如何在訪問者模式的上下文中注入變量。比如如果我遍歷樹結構,我想保留父級變量爲以前的級別執行一些在較低的水平。

回答

4

您可以在您的Visitor類中添加一個setContext()方法,告訴Visitor在哪個上下文中需要解釋以下對象。

當你有一個對象關係被多個層次嵌套時,你可以添加一個模擬的leaveContext()方法並在你的訪問者類中保存一堆上下文。

2

我認爲你的Visitor.visit方法應該像Visitor.visit(Class2,Class1)那裏你的訪問者類將實現每種類型的Class2的訪問方法。

這樣你就可以實現訪問(Class2-1,1類),訪(Class2-2,1類)...訪問(Class2-10,1類)

我想,這樣你就能夠訪問對象的Class1訪問方法內部和訪問方法調用將被動態決定,所以它不會不管你的Class2名單有什麼信息...

欲瞭解更多信息,你可以參考wiki頁面: http://en.wikipedia.org/wiki/Visitor_pattern

+0

讓我知道我是否以錯誤的方式解釋你的問題;) – Atul

2

以菲利普建議的更遠一步,試試這個。

鑑於類Widget是父,和階級特徵是子層次

使用簡單的基本類型:

// widget will have an instance of a Feature subclass from args or config, etc 
Widget theWidget = new Widget(args); 

// create and configure visitor 
Visitor theVisitor = new Visitor(); 
theVisitor.prop1 = x; 
theVisitor.prop2 = y; 
theVisitor.prop3 = z; 

theWidget.visit(theVisitor); 

的Widget(父類):

class Widget 
{ 
    Feature _childFeature; 

    void visit(Visitor visitor) 
    { 
     visitor.beginAccept(this); 
     childFeature.visit(visitor);    
     visitor.endAccept(); 
    } 

} 

功能類層次結構:

abstract class Feature 
{ 
    abstract void visit(Visitor visitor); 
} 

class Sunroof extends Feature 
{ 
    void visit(Visitor visitor) 
    { 
     visitor.accept(this); 
    } 
} 

class BulletProof extends Feature 
{ 
    void visit(Visitor visitor) 
    { 
     visitor.accept(this); 
    } 
} 

class GoldPlated extends Feature 
{ 
    void visit(Visitor visitor) 
    { 
     visitor.accept(this); 
    } 
} 

同時使用家長和孩子的具體訪問者:

class ExampleVisitor extends Visitor 
{ 

    private _widgetInProcess; 


    void beginAccept(Widget w) 
    { 
     _widgetInProcess = w; 
    } 

    void accept(Sunroof feature) 
    { 
     // do work based on both _widgetInProcess and type-specific feature 
    } 

    void accept(BulletProof feature) 
    { 
     // do work based on both _widgetInProcess and type-specific feature 
    } 

    void accept(GoldPlated feature) 
    { 
     // do work based on both _widgetInProcess and type-specific feature 
    } 

    void endAccept() 
    { 
     _widgetInProcess = null; 
    } 

} 

您可以可視化的樹模型用例以及其中beginAccept你推到棧上,各種accept方法偷看棧獲得他們的父上下文,以及從棧中彈出。這可以允許您遞歸處理樹,同時始終訪問父鏈。