vendredi 26 juillet 2019

Class-to-class communication design

I'm working on a project that has a class structure like this:

class A {
  constructor() {
    this.bInstances = this.makeBInstances(this);
  }

  makeBInstances() {
    // return new B()s
  }

  handleSomethingFromB() {
    // B did something and called this function so that A knows and can do stuff too
  }
}

class B {
  constructor(a) {
    this.a = a;
  }

  doSomething() {
    this.a.handleSomethingFromB( ... );
  }
}

I'm trying to figure out the best way for them to communicate with each other. Passing instances of classes around is not ideal, as it makes testing confusing, verbose and unreliable. Singletons are also vague and unreliable, sure they make it so I don't have to pass instances around, but I'm also having to import the instance and use it so that doesn't quite alleviate my problem. Reinitializing singletons for every test is also tiresome.

The best solution I've thought of thus far is to emit and listen for events. Like this:

class A {
  constructor() {
    // still need to do this?
    this.bees = this.makeBInstances();
    this.listenForBEvents();
  }

  makeBInstances() {
    // return new B()s
  }

  listenForBEvents() {
    document.addEventListener('event_from_class_B', () => {
      // react to B class' signal
      this.doSomething();
    });
  }

  doSomething() {
    // do something
  }
}

class B {
  constructor() {
    this.doCoolStuff();
  }

  doCoolStuff() {
    // Woohoo! I'm doing stuff!
    // create CustomEvent and emit it
    // handle that Event from other class(es)
  }
}

I like this because it makes testing very easy, and de-couples classes from dependencies. So as long as I emit an event that contains the right data, it doesn't matter what instances I have or where the data came from.

My question is: is this the right way to go? Are there any other alternatives?

Aucun commentaire:

Enregistrer un commentaire