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!");
- 활용
'Personal-Study > Design Patterns' 카테고리의 다른 글
[TS Design Patterns] 행동 패턴 - 반복자 (0) | 2023.11.05 |
---|---|
[TS Design Patterns] 행동 패턴 - 커맨드 (0) | 2023.11.05 |
[TS Design Patterns] 행동 패턴 - 책임 연쇄 (2) | 2023.11.01 |
[TS Design Patterns] 행동 패턴 - 옵저버 (0) | 2023.10.30 |
[TS Design Patterns] 구조 패턴 - 플라이웨이트 (0) | 2023.10.30 |
댓글