Mediator

한 집합에 속해있는 개체의 상호작용을 캡슐화 하는 객체를 정의한다. 객체들이 직접 서로를 참조하지 않도록 하여 객체 사이가 느슨한 결합(loose coupling)이 되도록 하며 개발자가 객체의 상호작용을 독립적으로 다양화시킬 수 있다.

mediator-pattern-diagram

  • Mediator

    Colleague 객체와 교류하는데 필요한 인터페이스 정의

  • ConcreteMedaitor

    Colleague 객체와 조화를 이뤄 Mediate 과정을 구현하며 Colleague들을 파악하고 관리한다.

  • Colleague

    자신의 Mediator 객체가 무엇인지 파악한다.

    다른 객체와 통신이 필요하면 Mediator를 통해 통신한다.

Mediator 패턴 적용

  • Mediator와 ConcreteMediator

    interface Mediator {
      notify: (sender: any, event: string) => void;
    }
    
    class ConcreteMediator implements Mediator {
      private firstColleague: Colleague;
      private secondColleague: Colleague;
    
      constructor(firstColleague: Colleague, secondColleague: SecondColleague) {
        this.firstColleague = firstColleague;
        firstColleague.setMediator(this);
        this.secondColleague = secondColleague;
        secondColleague.setMediator(this);
      }
    
      notify(sender: Colleague, event: string) {
        if (sender === this.firstColleague) {
          this.secondColleague.handler(sender, event);
        }
        if (sender === this.secondColleague) {
          this.firstColleague.handler(sender, event);
        }
      }
    }
    
  • Colleague와 Colleague 구현체

    abstract class Colleague {
      protected mediator: Mediator;
      setMediator(mediator: Mediator) {
        this.mediator = mediator;
      }
      abstract handler(sender: Colleague, event: string): void;
    }
    
    class FirstColleague extends Colleague {
      notifyEvent() {
        this.mediator.notify(this, "event from first");
      }
    
      handler(sender: Colleague, event: string) {
        console.log(`${event} from Mediator`);
      }
    }
    
    class SecondColleague extends Colleague {
      notifyEvent() {
        this.mediator.notify(this, "event from second");
      }
    
      handler(sender: Colleague, event: string) {
        console.log(`${event} from Mediator`);
      }
    }
    
  • Mediator 패턴 사용

    const firstColleague = new FirstColleague();
    const secondColleague = new SecondColleague();
    
    const mediator = new ConcreteMediator(firstColleague, secondColleague);
    
    firstColleague.notifyEvent();
    secondColleague.notifyEvent();
    
  1. Mediator가 각 객체에 대한 정보를 특정한 자료구조를 사용하여 저장하는 것이 바람직하다.

    현재는 Colleague가 2개기 때문에 문제가 없지만…. 늘어나면 복잡할것이다.

  2. Mediator 과정이 복잡해지면 이 패턴의 장점을 느낄수 없게된다.

    현재는 Colleague가 2개에 이벤트를 따로 분류 안해서 조건문이 2개지만 Colleague가 많아지거나 이벤트가 많아지면 mediation 과정은 복잡해질 것이다.

    따라서 필요에 따라 mediation 과정에서 sender만 분류하거나, 아니면 Mediator는 이벤트를 그대로 전달하고 각 Colleague가 알아서 선택해서 사용하는것도 선택할만한 방법인것 같다.