2012-10-26 104 views
0

我的困境是創建一個跟隨構建器模式的方法,該方法設置變量並返回自身,但我有一個接口Visitor,它由BasicVisitor實現,由其他訪客實現擴展。所有子類的一個構建器方法實現(泛型?)

此外,我有一個Visitable接口,該接口由SampleVisitable實現,並具有保存所有訪問者的歷史記錄的方法。


所以問題是,我想只保留在SampleVisitable歷史訪問者的完整引用,如果該訪問者是「重要的」,因爲主機訪問者訪問前調用Visitor.clean(),其清洗所有的來自上次訪問的數據,但我希望「重要」訪問者數據保留在歷史記錄中。

這是我迄今爲止的實施:

public interface Visitor { 
    public void visit(Visitable visitable); 

    public Visitor clone(); 

    public <V extends Visitor> V important(); 

    public boolean isImportant(); 
} 

這是從SampleVisitable類的一個片段:

public void accept(Visitor visitor) { 
    visitor.clean(); 
    visitor.visit(this); 
    addToHistory(visitor); // only adds if visitor.isImportant() == true 
} 

然後,我有BasicVisitor它實現了important()方法。現在我不想每次都要重寫important()方法,但是我必須執行我的實現,因爲如果任何其他訪問者使用「無法從BasicVisitor轉換爲[OtherVisitor]」的形式,就會出現表單錯誤important()方法不覆蓋它:

OtherVisitor otherVisitor = new OtherVisitor().important(); // cannot convert from BasicVisitor to OtherVisitor error. 

這樣做的最佳方法是什麼?我需要實現此功能一次,並可供所有其他子類使用,而不要求它們覆蓋它。謝謝!

編輯:

哇,抽象類的正是我一直在尋找!我做了更多的研究,並在differences between interfaces and abstract classes上找到了這篇文章,我希望它能幫助其他人尋找答案。

當我發佈這個答案後,我意識到我不必在這種情況下使用生成器模式,我可以創建一個setImportant(boolean isImportant),基本上我需要的東西,但我很高興我反問,因爲這是我需要的另一個設計問題。

EDIT2:

試圖抽象類後,我的主要問題依然存在,我還是要覆蓋每個子類Visitorimportant()方法。

伊利亞

回答

1

請試試這個。如果您使用abstract類,那麼您實現的方法將適用於所有子類。

public abstract class Visitor { 
    public abstract void visit(Visitable visitable); 

    public abstract Visitor clone(); 

    public abstract <V extends Visitor> V important(); 

    public boolean isImportant() { 
     //logic to store important visitors 
    } 
} 
+1

抽象類中缺少空間,您的代碼將永遠不會編譯。此外,我不知道爲什麼這解決了他的問題。 –

+0

謝謝托馬斯我編輯。 – sunleo

+1

它仍然不會編譯,因爲沒有實現的方法需要是抽象的。更好的做法是實現他的界面並覆蓋最後的方法。儘管如此,這並不能解決他的問題。 –

0

我能解決使用abstract class這個問題,因爲在@sunleo他的答覆中提到,並改變important()設計器功能的二傳手setImportant(boolean isImportant)和仿製藥。

所以現在我有以下實現:

public abstract class Visitor<T> implements Cloneable { 
    private boolean important = false; 
    private Graphable host; 

    @Override 
    public Visitor<T> clone() { 
     try { 
      return (Visitor<T>) super.clone(); 
     } 
     catch(CloneNotSupportedException exception) { 
      log.info(exception, exception);   
     } 
     return null; 
    } 

    public Graphable getHost() { 
     return host; 
    } 

    public boolean isImportant() { 
     return important; 
    } 

    public void setHost(Graphable host) { 
     this.host = host; 
    } 

    public void setImportant(boolean isImportant) { 
     important = isImportant; 
    } 

    public void visit(Graphable graphable) { 
     if(graphable instanceof Node) { 
      visit((Node) graphable); 
     } 
     else if (graphable instanceof Edge) { 
      visit((Edge) graphable); 
     } 
    } 

    public abstract void clean(); 

    public abstract void visit(Edge edge); 

    public abstract void visit(Node node); 
} 

隨着Visitor是可複製的,它可以很容易地作出保留一個副本在我的歷史。

相關問題