首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为需要访问共享状态数据的多个侦听器提供适当的耦合

为需要访问共享状态数据的多个侦听器提供适当的耦合
EN

Stack Overflow用户
提问于 2008-11-09 00:56:42
回答 3查看 1K关注 0票数 0

使用传统的侦听器回调模型。我有几个听众,他们收集各种各样的东西。每个监听器收集的内容都在监听器内部的内部结构中。

问题是,我希望一些监听器知道其他监听器中的一些“东西”。

我强制执行监听器注册顺序,因此,如果我故意按某种顺序注册事件,则后面的监听器可以确保之前的监听器更新了它的内容,并以某种方式访问它来做更多的事情。

我的第一个尝试是让每个侦听器存储对它所依赖的侦听器的引用。因此,我按照没有依赖项的侦听器与具有先前注册的依赖项的侦听器的顺序注册侦听器,然后用各种方法设置侦听器之间的引用。

我开始意识到这种感觉有多糟糕,我想知道以前是不是也经历过这种情况。当一个监听器需要访问另一个监听器中的内容时,哪种模式更合适?

下面是一些伪代码来说明:

代码语言:javascript
复制
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);
   }
 }
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2008-11-10 21:26:18

为什么不创建一个中心对象来跟踪所有侦听器类的onEvent方法被触发的次数

代码语言:javascript
复制
 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
票数 1
EN

Stack Overflow用户

发布于 2008-11-09 01:21:18

你在这里描述了很多耦合。最好的方法是消除所有这些反向通道依赖,但如果做不到这一点,您可能会让那些具有依赖关系的侦听器不在初始侦听器列表上侦听,而是在它们所依赖的任何东西上侦听。或者你可以让他们等他们得到所有的信号。

您可以通过让侦听器识别它们所依赖的对象来自动化依赖项管理。侦听器列表将不按插入顺序排序,而是确保依赖对象遵循其依赖关系。您的侦听器接口将如下所示:

代码语言:javascript
复制
interface Listener {
  String getId();
  Collection<String> getDependencies();
  onEvent(char e);
}

或者只是引用,就像这样:

代码语言:javascript
复制
interface Listener {
  Collection<Listener> getDependencies();
  onEvent(char e);
}
票数 2
EN

Stack Overflow用户

发布于 2008-11-10 02:53:23

“我们如何改变这一点,使监听器B知道监听器A?或者甚至不知道,只是以某种方式耦合?”

您通常不希望像这样将两个“对等”对象耦合在一起。您希望两个对等点依赖于一些共同的东西。

更深层次的问题是,听众A或听众B对他们收集的所有信息做了什么?

侦听器通常做两件事:它收集数据并采取行动。通常,这两件事需要分开。听众应该倾听,收集和做更多的事情。监听程序可以激活一些其他对象。

你可能只有一个监听器,它有几个动作(A和B)。然后,监听器可以向A和B提供适当的计数。它向A提供'a‘计数。它向B提供'a’或'b‘计数。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/275456

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档