适当的耦合对于多的听众的需要访问的共同国家数据
-
07-07-2019 - |
题
工作与传统的监听器回调的模式。我有几个听众,收集各种各样的东西。每个监听是收集东西是内部的监听器在内部结构。
问题是我想要的一些听众可以知道一些的"东西"在其他听众。
我强听众登记的顺序,因此如果我故意注册活动,在一些为了后来的听众可以肯定的是,以前听众更新了它的东西,以某种方式访问它做更多的东西。
我第一次尝试这是每个监听器储存引听众它所依赖的.所以我寄存器的听众在那些没有依赖关系到那些事先登记的相关性,然后设定之间的引听众的各种方法。
我开始意识到这种感觉多么糟糕,我想知道如果以某种方式已经沿着这条道路。是什么将是一个更合适的模式之一时听众需要访问的东西在另一个?
这里是一些伪来说明:
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);
}
}
}
解决方案
为什么没有一个中心对象将继续跟踪多少次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
其他提示
你已经描述了很多联接在这里。最好的是消除所有这回通道依赖性,但如果做不到这一点也许你可以有那些依赖听力不是在最初的听者名单,但不管他们是依赖。或者你可以让他们等到他们拥有所有的信号。
你可以自动依赖关系的管理具有听众识别他们是谁的依赖。听者名单将被命令不能通过插入秩序,但以确保依赖的对象按照他们的依赖性。你听众的接口看起来是这样的:
interface Listener {
String getId();
Collection<String> getDependencies();
onEvent(char e);
}
或者只是有引用,如下所示:
interface Listener {
Collection<Listener> getDependencies();
onEvent(char e);
}
"我们将如何改变这一点,以便听B听众知道吗?或甚至不知道,只是以某种方式联接?"
你不经常需要几个两种"对等的"对象这样的。你想要的两个同事来取决于共同的东西.
更深层的问题是什么,听众或听众B做的所有信息,他们收集?
监听通常做两件事:它收集数据和它采取的行动。通常这两个东西需要被分开。听众,应该听取并收集和做多一点。其他一些目(s)可以被激活,以通过有监听器。
什么你可能仅仅是一个监听它已采取若干行动(A和B)。听众可,然后提供适当计数为一个以及B它提供了一个'a'count to A。它提供了一个"a"或"b"计B。