Typescript로 다시 쓰는 GoF - Mediator

아홉번째태양·2023년 10월 10일
0

Mediator Pattern?

여러개의 객체들이 상호의존적인 상황에서 각 객체들간의 결합성을 낮추기 위해 사용하는 패턴이다. 각 객체들이 서로의 상태를 확인하며 동작하는대신, 중재자 역할을 담당하는 하나의 중심 객체를 통해 행동을 지시 받는다.

언제 쓸까?

보통 프론트를 구성할 때 많이 볼 수 있으며, [[MVC 패턴]]의 Controller가 중재자Mediator의 역할을 수행한다.

구현

패턴을 구성하는 객체들

  1. Mediator 중재자
    Colleague들에게 지시를 내릴 인터페이스를 정의
  2. ConcreteMediator 구체적인 중재자
    Mediator의 인터페이스를 구현
  3. Colleague 동료
    Mediator와 소통하는 객체들이며 어떻게 Mediator와 통신할지 인터페이스를 정의
  4. ConcreteColleague 구체적인 동료
    Colleague의 인터페이스와 각각의 객체가 맡은 역할/임무를 구현한다.

Mediator

interface Mediator {
  notify(sender: object, event: string): void;
}

ConcreteMediator

class ConcreteMediator implements Mediator {
  constructor(
    private readonly component1: Component1,
    private readonly component2: Component2,
  ) {
    this.component1.setMediator(this);
    this.component2.setMediator(this);
  }

  notify(sender: object, event: string): void {
    if (event === 'A') {
      console.log('Mediator reacts on A and triggers following operations:');
      this.component2.doC();
    }

    if (event === 'D') {
      console.log('Mediator reacts on D and triggers following operations:');
      this.component1.doB();
      this.component2.doC();
    }
  }
}

Colleague

class Colleague {
  declare protected mediator: Mediator;

  setMediator(mediator: Mediator): void {
    this.mediator = mediator;
  }
}

ConcreteColleague

class Component1 extends Colleague {
  doA(): void {
    console.log('Component 1 does A.');
    this.mediator.notify(this, 'A');
  }

  doB(): void {
    console.log('Component 1 does B.');
    this.mediator.notify(this, 'B');
  }
}

class Component2 extends Colleague {
  doC(): void {
    console.log('Component 2 does C.');
    this.mediator.notify(this, 'C');
  }

  doD(): void {
    console.log('Component 2 does D.');
    this.mediator.notify(this, 'D');
  }
}

실행

const c1 = new Component1();
const c2 = new Component2();
const mediator = new ConcreteMediator(c1, c2);

// Client triggers A
const handlerA = () => c1.doA();

// Client triggers D
const handlerD = () => c2.doD();

Pub/Sub과의 유사성?

구성원들이 중앙집권적인 어떤 객체를 거쳐서 통신하는 모습이 Pub/Sub과 유사하지만 두 패턴의 목적이 다르다.

Pub/Sub 패턴

Pub/Sub 패턴은 중계에 그 목적이 있다.
한 구성원에게서 받은 메세지를 다른 모든 구성원들에게 어떻게 전달할지를 구현하기 위한 패턴이다.

하지만 넓은 의미에서 Mediator 패턴의 한 부분으로서 Pub/Sub 패턴이 사용될 수는 있다.

참고자료

Java언어로 배우는 디자인 패턴 입문 - 쉽게 배우는 Gof의 23가지 디자인패턴 (영진닷컴)

Refactoring Guru - Mediator

디자인 패턴 톺아보기 - Mediator Pattern

0개의 댓글