공유 상태 데이터에 액세스 해야하는 여러 리스너를위한 적절한 커플 링

StackOverflow https://stackoverflow.com/questions/275456

  •  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가 청취자가 알 수 있도록 어떻게 이것을 바꾸겠습니까?

당신은 종종 이와 같은 두 개의 "피어"객체를 몇 개씩두고 싶지 않습니다. 당신은 두 동료가 일반적인 것에 의존하기를 원합니다.

더 깊은 질문은 청취자 A 또는 청취자 B가 수집 한 모든 정보로 무엇을 하는가?

청취자는 종종 두 가지 작업을 수행합니다. 데이터를 수집하고 조치를 취합니다. 종종이 두 가지를 분리해야합니다. 청취자는 듣고 수집하고 조금 더해야합니다. 다른 객체 (들)는 청취자가 활성화 할 수 있습니다.

당신이 가질 수있는 것은 몇 가지 행동 (a와 b)을 가진 하나의 청취자입니다. 청취자는 A와 B에 적절한 카운트를 제공 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top