2011-12-05 21 views
2

我今天做了一些功課與訪問者模式,和我做了有些看起來像這樣(編輯示例代碼wikipedia)訪問者:與訪問者模式的一些非常通用的代碼

class CarElementPrintVisitor implements CarElementVisitor { 
    public void visit(CarElement element) {  
     if (element.getClass() == Wheel.class) 
     { 
      return visit((Wheel)element); 
     } 
     else if (element.getClass() == Engine.class) 
     { 
      return visit((Engine)element); 
     } 
     else if (element.getClass() == Body.class) 
     { 
      return visit((Body)element); 
     } 
     else //if (v.getClass() == Car car.class) 
     { 
      return visit((Car)element); 
     } 
    } 

    public void visit(Wheel wheel) {  
     System.out.println("Visiting " + wheel.getName() + " wheel"); 
    } 

    public void visit(Engine engine) { 
     System.out.println("Visiting engine"); 
    } 

    public void visit(Body body) { 
     System.out.println("Visiting body"); 
    } 

    public void visit(Car car) {  
     System.out.println("Visiting car"); 
    } 
} 

的「 public void visit(CarElement element)「方法是醜陋的(如果添加更多的CarElements,需要維護),但是我想保留這個方法,所以我試圖做得更好。

最後我想這一點:

public void visit(CarElement element) {  
     return visit(element.getClass().cast(element)); 
    } 

但這只是返回「訪華(CarElement元素)」,即使element.getClass()返回正確的類,所以它在一個無限循環結束。

有誰知道該怎麼做,我正在做什麼? (如果這是可能的,我不確定)。

回答

3

你錯過了什麼讓訪問者模式的美:accept(CarElementVisitor)方法必須在CarElement接口,和一個稱爲訪問者回來本身,使用選擇恰當的類型。重新閱讀維基百科文章。

+0

+1這就是我所說的。 –

+0

該死的我現在變笨了,非常感謝。當stackoverflow允許我接受答案。 – Webbies

1

最後一個版本的問題是,您嘗試在運行時嘗試使用Java不支持的重載。 Java可以根據調用方法的對象的類型將調用分派給各種實現,而不是基於參數的類型。

這裏是Visitor模式的樣本,其將作爲您(希望)希望:

class EventA { 
    void accept(Visitor visitor) { 
     visitor.visit(this); 
    } 
} 

class EventB { 
    void accept(Visitor visitor) { 
     visitor.visit(this); 
    } 
} 

interface Visitor { 
    void visit(EventA e); 
    void visit(EventB e); 
} 

class VisitorImpl implements Visitor { 
    public void visit(EventA e) { 
     System.out.println("EventA"); 
    } 

    public void visit(EventB e) { 
     System.out.println("EventB"); 
    } 
} 

public class Main { 

    public static void main(String[] args) { 
     EventA event = new EventA(); 
     event.accept(new VisitorImpl()); 
    } 

} 

請注意,您仍然需要每次添加新類型的參觀時間延長遊客接口。 並參見我的this答案。

希望,這有助於位)

0

您可以在CarElement上使用抽象方法。

public abstract void visit(); 

class Wheel extends CarElement { 
    public void visit() { 
     System.out.println("Visiting " + getName() + " wheel"); 
    } 
} 

CarElement ce = new Wheel(); 
ce.visit();