2008-11-09 61 views
0

使用傳統的偵聽器回調模型。我有幾個聽衆收集各種東西。每個偵聽器收集的內容都在內部結構的偵聽器中。正確耦合需要訪問共享狀態數據的多個偵聽器

的問題是,我想一些聽衆要注意的一些在其他聽衆的「東西」。

我執行偵聽器註冊順序,所以如果我明知註冊以某種順序事件後聽衆可以肯定的是先前聽衆更新了東西,並以某種方式訪問​​它做更多的東西。

我在第一次嘗試讓每個聽者存儲其所依賴聽衆的參考。因此,我按照沒有依賴關係的順序將偵聽器註冊到那些具有預先註冊依賴關係的偵聽器中,然後用各種方法在偵聽器之間設置引用。

我開始意識到多麼糟糕這感覺,我想知道,如果不知何故以前一直沿着這條道路。當其中一位聽衆需要訪問另一位聽衆時,什麼會是更合適的模式?

下面是一些僞代碼來說明:

interface Listener { onEvent(char e); } 

class A implements Listener { 
    private int count; 
    public void onEvent(char e) { if(e == 'a') count++; } 
    public int getCount() { return count; } 
} 

class B implements Listener { 
private int count; 
// private A a; 
// private void setA(A a) { this.a = a; } 

public void onEvent(char e) { if(e == 'b') count++; } 
public int getCount() { return count; } 
public int getAPlusBCount() { 
    // We know B count, but we don't know A so how would we change this 
    // so B is A aware? Or not even aware, just somehow coupled? This 
    // is the question 
    // return a.getCount() + count; 
} 

public void doConditionalHere() { 
    // Do some condition in B that relies on the state of data in A 
    int acount = 0; // a.getCount(); ??? 
    if(acount % 2 == 0) { 
    this.count--; 
    } 
} 
} 

class Run { 
A a = new A(); 
B b = new B(); 
List listeners = new List(); 
listeners.add(a); 
listeners.add(b); 

// The ugly way I add coupling right now is to keep a reference to A 
// inside B. It's commented out because I am hoping there is a more intelligent approach 
// b.setA(a); 

for(char c : "ababbabab") { 
    for(listener : listeners) { 
    listener.onEvent(c); 
    } 
} 
} 
+0

「我要繼續前進,並接受你的答案,因爲它的工作原理,但我希望爲一些其他的方式。」這很愚蠢。爲什麼接受它?爲什麼不等待更好的答案? – 2008-11-10 02:53:56

+0

好的,我會等的。 – Josh 2008-11-10 14:36:06

回答

1

爲什麼不能有一箇中央對象,將跟蹤了多少次的onEvent方法被解僱了所有的監聽類

public interface CountObserver { 

public void updateCount(String className); 
public int getCount(String className); 
} 

public class CentralObserver implements CountObserver { 

private int aCount; 
private int bCount; 

public void updateCount(String className) { 

//There's probably a better way to do this than using 
//all these if-elses, but you'll get the idea. 

    if (className.equals("AclassName")) { 
    aCount++; 
    } 
    else if (className.equals("BclassName")) { 
    bCount++; 
    } 
} 

public int getCount(String className) { 

    if (className.equals("AclassName")) { 
    return aCount; 
    } 
    else if (className.equals("BclassName")) { 
    return bCount; 
    } 
} 

class A implements Listener { 

CountObserver countObserver; 

public void registerObserver (CountObserver countObserver) { 

    this.countObserver = countObserver; 
} 

public void onEvent(char e) { 

    if(e == 'a') { 

    countObserver.updateCount (this.getClass.getName); 
    } 
} 

} 

//Same thing for B or any other class implementing Listener. Your Listener interface should, of 

//course, have a method signature for the registerObserver method which all the listener classes 

//will implement. 

class Run { 

private A a; 
private B b; 
private CountObserver centralObserver; 

public runProgram() { 

    centralObserver = new CentralObserver(); 
    a.registerObserver(centralObserver); 
    b.registerObserver(centralObserver); 

//run OnEvent method for A a couple of times, then for B 

} 

public int getAcount() { 

return centralObserver.getCount(a.getClass.getName()); 
} 

public int getBcount() { 

return centralObserver.getCount(b.getClass.getName()); 
} 
} 
//To get the sum of all the counts just call getAcount + getBcount. Of course, you can always add more listeners and more getXCount methods 
2

你描述這裏有很多的耦合。最好的做法是消除所有這種反向通道依賴性,但是如果失敗了,也許你可以讓那些依賴性不在最初的監聽器列表上,而是監聽它們依賴的任何依賴項。或者你可以讓他們等待,直到他們擁有了所有的信號。

您可以通過讓偵聽器識別他們依賴的人來自動執行依賴關係管理。偵聽器列表將不會按插入順序排序,而是要確保依賴對象遵循其依賴關係。您的偵聽器接口會是這個樣子:

interface Listener { 
    String getId(); 
    Collection<String> getDependencies(); 
    onEvent(char e); 
} 

或只是有引用,就像這樣:

interface Listener { 
    Collection<Listener> getDependencies(); 
    onEvent(char e); 
} 
+0

你能否澄清你的意思是「反向通道」依賴? – Josh 2008-11-09 01:32:05

+0

監聽器間依賴關係。 – sblundy 2008-11-09 01:53:14

1

「我們怎麼會改變這一點,以便監聽B是聽者知道或者甚至沒有?意識到,只是以某種方式耦合?「

你不經常想要連接兩個這樣的「同級」對象。你希望兩個同齡人依靠一些共同點。

更深層次的問題是什麼監聽器或監聽器B沒有與他們收集的所有信息?

聽衆經常做兩件事:收集數據並採取行動。通常這兩件事情需要分開。聽衆應該傾聽並收集並做更多。其他一些對象可以由Listener激活。

你可能只有一個聽衆有幾個動作(A和B)。然後,聽衆可以對提供適當的計數以及B.它提供了一個「一」數到A.它提供了一個「A」或「B」數到B.