dimanche 31 janvier 2021

Class composition in TypeScript

I want to build a class that can compose multiple objects and use any of their interfaces.

Class A can use any of the interfaces of Class B and C

B can use any of the interfaces of C

C can use any of the interfaces of B

I have the above functionality written in JavaScript and I was wondering what's the best and correct way to achieve the same using TypeScript:

import { findLast, isFunction } from "lodash";

class Composite {
  constructor(behavior) {
    this.behaviors = [];

    if (behavior) {
      this.add(behavior);
    }
  }

  add(behavior) {
    behavior.setClient(this);
    this.behaviors.push(behavior);
    return this;
  }

  getMethod(method) {
    const b = findLast(this.behaviors, (behavior) =>
      isFunction(behavior[method])
    );
    return b[method].bind(b);
  }
}

class Behavior1 {
  foo() {
    console.log("B1: foo");
  }

  foo2() {
    console.log("B1: foo2");
    this.getMethod("bar")();
  }

  setClient(client) {
    this.client = client;
  }

  getMethod(method) {
    return this.client.getMethod(method);
  }
}

class Behavior2 {
  foo() {
    console.log("B2: foo");
    this.getMethod("foo2")();
  }

  bar() {
    console.log("B2: bar");
  }

  setClient(client) {
    this.client = client;
  }

  getMethod(method) {
    return this.client.getMethod(method).bind(this);
  }
}

const c = new Composite();
c.add(new Behavior1());
c.add(new Behavior2());
c.getMethod("foo")();
c.getMethod("bar")();

// Output:
// B2: foo
// B1: foo2
// B2: bar
// B2: bar

Link to codesandbox: https://codesandbox.io/s/zen-poitras-56f4e?file=/src/index.js

Aucun commentaire:

Enregistrer un commentaire