2015-11-13 29 views
2

在JAVA我經常使用這種模式:爪哇聽者除去

class A{ 
    void addListener(Listener obj); 
    void removeListener(Listener obj); 
} 

class B { 
    private A a; 

    B(A a){ 
     this.a=a; 
     a.addListener(myListener) 
    } 

    private final myListener=new Listener(){ 
     void listener(); 
    } 

    public void dispose(){ 
     a.removeListener(); 
    } 
} 

通常A表示的數據集和B需要通過添加監聽到對象A,以這樣做是在A中的數據的變化作出反應當一個新的B實例被構造時。
由於對象a存在於A之外,因此此方法迫使我創建一個dispose()方法,該方法將偵聽器從對象a中移除。

雖然我知道精心設計的JAVA代碼通常不需要dispose()方法。 這種模式是一種糟糕的設計嗎?你能否提出其他方法?

在此先感謝您的幫助。

+0

這可能是相關的:http://stackoverflow.com/questions/171952/is-there-a-destructor-for-java –

回答

0

通常我會避免使用需要A作爲參數的構造函數。具有無參數構造函數的模式更易於閱讀,允許序列化,允許更靈活地重用對象等。

同樣在您的代碼中,在調用dispose之後有一段時間你有一個'斷開'B。如果在這段時間內調用方法,則必須處理錯誤條件。

所以,使其更萬無一失:

class B { 
    private A a=null; 

    B(){} 

    public connectToA(A a){ 
    if(a!=null) throw new RuntimeException(...); 
    this.a=a; 
    a.addListener(myListener) 
    } 

    private final myListener=new Listener(){ 
    void listener(); 
    } 

    public void disconnectFromA(){ 
    if(a==null) throw new RuntimeException(...) 
    a.removeListener(); 
    } 
} 

如果你真的想你的連接是存在每當B存在,當B不再存在,考慮嘗試在終結斷開被刪除。

+0

你的答案更關注模式的優惠。如果你需要設置**'a',可以這樣做構造函數。 –

+0

同意。完成同樣的事情有很多種方式,但有些比其他更明確。 **在調用'dispose'之後,要求設置**'a'會產生問題。在這種情況下,重寫'finalize'可能是正確的解決方案? –