본문 바로가기
Personal-Study/Design Patterns

[TS Design Patterns] 행동 패턴 - 중재자

by Aaron-Kim 2023. 11. 4.

Mediator (Intermediary, Controller)

- 객체 간의 혼란스러운 의존 관계를 줄일 수 있음

- 객체 간의 직접 통신을 제한하고 중재자 객체를 통해서만 협력하도록 함

- 서로 독립적으로 작동해야 하는 컴포넌트 간의 모든 직접 통신을 중단한 후,

   대신 이러한 컴포넌트들은 호출들을 적절한 컴포넌트들로 리다이렉션하는 특수 중재자 객체를 호출하여

   간접적으로 협력하도록 제안함 -> 단일 중재자 클래스에만 의존하게 됨

- ex) 모든 항공 통신은 비행기 관제탑을 통해 이루어짐

- 일부 클래스들이 다른 클래스들과 단단하게 결합하여 변경하기 어려울 때 사용

- 타 컴포넌트들에 너무 의존해서 다른 프로그램에서 컴포넌트를 재사용할 수 없을 때 사용

- 몇 가지 기본 행동을 다양한 콘텍스트들에서 재사용하기 위해 수많은 컴포넌트 자식 클래스들을

   만들고 있는 스스로를 발견했을 때 사용

- MVC 패턴의 컨트롤러 부분의 동의어는 중재자임

 

- Mediator/Middleware

- 중재자 역할을 하는 객체를 통해 컴포넌트들이 서로 통신하도록 함

- 중재자는 보통 객체나 함수로 구현됨

- ex) 공항에서 비행기 동선을 관리하는 관제소

- 객체끼리 서로 통신하여 다대다 관계를 이루는 대신 객체들의 요청을 모두 중재자 객체로 보냄

- 실무에서 채팅 구현할 때 많이 사용

- Express.js에서 특정 라우팅 경로에 대해 콜백을 추가함으로써 요청 처리 가능

  - next 함수는 요청-응답 사이클에 걸려있는 다음 콜백을 호출함

- 여러 객체 간 다대다 통신을 하나의 관리 포인트를 통하도록 만들어 관계를 단순하게 만들어줌

 

- 예시

 

/**
 * The Mediator interface declares a method used by components to notify the
 * mediator about various events. The Mediator may react to these events and
 * pass the execution to other components.
 */
interface Mediator {
    notify(sender: object, event: string): void;
}

/**
 * Concrete Mediators implement cooperative behavior by coordinating several
 * components.
 */
class ConcreteMediator implements Mediator {
    private component1: Component1;

    private component2: Component2;

    constructor(c1: Component1, c2: Component2) {
        this.component1 = c1;
        this.component1.setMediator(this);
        this.component2 = c2;
        this.component2.setMediator(this);
    }

    public 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();
        }
    }
}

/**
 * The Base Component provides the basic functionality of storing a mediator's
 * instance inside component objects.
 */
class BaseComponent {
    protected mediator: Mediator;

    constructor(mediator?: Mediator) {
        this.mediator = mediator!;
    }

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

/**
 * Concrete Components implement various functionality. They don't depend on
 * other components. They also don't depend on any concrete mediator classes.
 */
class Component1 extends BaseComponent {
    public doA(): void {
        console.log('Component 1 does A.');
        this.mediator.notify(this, 'A');
    }

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

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

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

/**
 * The client code.
 */
const c1 = new Component1();
const c2 = new Component2();
const mediator = new ConcreteMediator(c1, c2);

console.log('Client triggers operation A.');
c1.doA();

console.log('');
console.log('Client triggers operation D.');
c2.doD();

 

class ChatRoom {
  logMessage(user, message) {
    const sender = user.getName();
    console.log(`${new Date().toLocaleString()} [${sender}]: ${message}`);
  }
}

class User {
  constructor(name, chatroom) {
    this.name = name;
    this.chatroom = chatroom;
  }

  getName() {
    return this.name;
  }

  send(message) {
    this.chatroom.logMessage(this, message);
  }
}

const chatroom = new ChatRoom();

const user1 = new User("John Doe", chatroom);
const user2 = new User("Jane Doe", chatroom);

user1.send("Hi there!");
user2.send("Hey!");

 

- 활용


[아티클]

[TS 사용 예시]

[UI Component] Design Patterns - Mediator/Middleware

반응형

댓글