Proper Kupplung für mehrere Zuhörer, die gemeinsam genutzte Zustandsdaten, auf die zugegriffen brauchen

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

  •  07-07-2019
  •  | 
  •  

Frage

Arbeiten mit einem traditionellen Hörer Callback-Modell. Ich habe mehrere Zuhörer, die verschiedene Sachen zu sammeln. Jeder Zuhörer gesammelt Zeug ist im Inneren des Hörers in internen Strukturen.

Das Problem ist, dass ich einige der Zuhörer von einigen der „Stoff“ bewusst zu sein, wollen in den anderen Zuhörern.

I Zuhörer Registrierung, um durchzusetzen, also wenn ich wissentlich Ereignisse in einer bestimmten Reihenfolge sicher sein, ein später Zuhörer registrieren kann, dass ein zuvor Zuhörer seine Sachen aktualisiert und es irgendwie mehr Dinge tun zugreifen.

Mein erster Versuch, das ist jeder Zuhörer einen Verweis speichern, um die Zuhörer zu haben, bei denen es abhängt. So registrieren ich Zuhörer in der Reihenfolge derjenigen, ohne Abhängigkeiten zu denen mit Abhängigkeiten vor-registriert, und legen Sie dann die Verweise zwischen den Zuhörer in verschiedenen Verfahren.

Ich beginne zu erkennen, wie schlecht das fühlt sich an, und ich frage mich, ob irgendwie vor auf diesem Weg war. Was ein geeignetes Muster sein würde, wenn einer der Zuhörer Sachen in einem anderen zugreifen muss?

Hier finden Sie einige Pseudo-Code zu veranschaulichen:

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);
   }
 }
}
War es hilfreich?

Lösung

Warum nicht eine zentrale Aufgabe, die verfolgt, wie oft onEvent Methode wurde für alle Zuhörer Klassen gefeuert halten

 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

Andere Tipps

Sie haben die Beschreibung hier viele Kopplung. Am besten wäre es all diesen Rückkanal Abhängigkeit zu beseitigen, aber in Ermangelung eines solchen vielleicht haben Sie diejenigen mit Abhängigkeiten konnte nicht auf dem ursprünglichen Zuhörer Liste hören, aber auf was auch immer sie sind abhängig von. Oder Sie könnten sie haben warten, bis sie alle Signale haben.

Sie könnten das Abhängigkeitsmanagement automatisieren, indem die Zuhörer mit identifizieren, wer sie sind abhängig. Die Zuhörer Liste würde nicht durch Auftrag bestellt werden, aber abhängigen Objekte folgen, ihre Abhängigkeit zu versichern. Ihre Zuhörer Schnittstelle etwas wie folgt aussehen:

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

oder einfach nur die Referenzen, etwa so:

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

„Wie würden wir dies ändern, so dass Zuhörer B Zuhörer A bewusst? Oder nicht einmal bewusst, nur irgendwie verbunden?“

Sie wollen nicht oft zu koppeln zwei „Peer“ Objekte wie diese. Sie möchten zwei Kollegen gemeinsam auf etwas abhängig zu sein.

Die tiefere Frage ist, was macht Listener A oder B Zuhörer tun mit all den Informationen, die sie sammeln?

Ein Zuhörer oft tut zwei Dinge: er sammelt Daten und ergreift Maßnahmen. Oft müssen diese beiden Dinge getrennt werden. Zuhörer sollten hören und sammeln und etwas mehr tun. Einige andere Objekt (e) von einem Listener aktiviert werden.

Was Sie haben können, ist nur ein Zuhörer, die mehrere Aktionen (A und B). Der Hörer kann dann entsprechende Zählungen zu A bereitzustellen sowie B. Es ist ein ‚a‘ zählen, A. bietet Es stellt ein ‚a‘ oder ‚b‘ zählen, B.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top