interface Shape {
  area(): number;
}

class Circle implements Shape {
  constructor(private readonly radius: number) {}

  area(): number {
    return Math.PI * Math.pow(this.radius, 2);
  }
}

class Square implements Shape {
  constructor(private readonly length: number) {}

  area(): number {
    return Math.pow(this.length, 2);
  }
}

class Triangle implements Shape {
  constructor(private readonly length: number) {}

  area(): number {
    return Math.pow(this.length, 2); // à modifier pour aire du triangle
  }
}

// Imaginons qu'on ajoute une autre forme ...

class AreaCalculator {
  constructor(private readonly shapes: Shape[]) {}

  public sum(): number {
    return this.shapes.reduce((total, shape) => total + shape.area(), 0);
  }
}

class SumConsoleOutputter {
  constructor(private readonly calculator: AreaCalculator) {}

  public output(): void {
    const sum = this.calculator.sum();
    console.log(`Somme des aires : ${sum}`);
  }
}

const calculator = new AreaCalculator([new Circle(5), new Square(4), new Triangle(3)]);
const outputter = new SumConsoleOutputter(calculator);

outputter.output(); // affiche la somme des aires

export default {};

class EventBus {
  constructor(private readonly handlers: any = {}) {}

  public registerHandler(type: string, handler: (msg: any) => void) {
    this.handlers[type] = handler;
  }

  public dispatch(msg: any) {
    const handler = this.handlers[msg.type]
    handler(msg);
  }
}

const bus = new EventBus();

bus.registerHandler('msg_a', (msg: any) => console.log(msg));
bus.registerHandler('msg_b', (msg: any) => console.log(msg));
bus.registerHandler('msg_c', (msg: any) => console.log(msg));
bus.registerHandler('msg_d', (msg: any) => console.log(msg));

bus.dispatch({ type: 'msg_a' })
bus.dispatch({ type: 'msg_b' })
bus.dispatch({ type: 'msg_c' })
