Skip to main content

Decorator Pattern

View all Design Patterns

객체에 동적으로 책임을 추가해 객체를 동적으로 확장할 수 있는 방법이다. 기본적으로 상속 관계는 정적이며, 자식 클래스는 하나의 부모 클래스만 가질 수 있다. Decorator Pattern은 상속 관계가 아닌 집합 또는 합성 관계로 이를 해결한다.


Class Diagram

Abstract overview

Concrete example


Code

interface Request {
message: string;
}

interface Response {
message: string;
}

interface RequestHandler {
handleRequest(request: Request): Response;
}

class ConcreteHandler implements RequestHandler {
handleRequest(request: Request): Response {
return { success: true };
}
}

abstract class MiddlewareDecorator {
protected handler: RequestHandler;

constructor(handler: RequestHandler) {
this.handler = handler;
}

abstract handleRequest(request: Request): Response;
}

class LoggingMiddleware extends MiddlewareDecorator {
handleRequest(request: Request): Response {
console.log("Logging request...");
return this.handler.handleRequest(request);
}
}

class AuthenticationMiddleware extends MiddlewareDecorator {
handleRequest(request: Request): Response {
console.log("Authentication request...");
return this.handler.handleRequest(request);
}
}

const handler = new ConcreteHandler();
const logger = new LoggingMiddleware(handler);
const authenticator = new AuthenticationMiddleware(logger);

const response = authenticator.handleRequest({
message: "This is request message",
});
console.log(response);
//Authentication request...
// Logging request...
// { success: true }

ConcreteHandlerLoggingMiddlewareAuthenticationMiddleware

위와 같이 서버의 미들웨어를 순서대로 추가하는 예시를 들 수 있다.


Pros and Cons

Pros

  • 기존 코드의 변경 없이 런타임 시 객체에 새로운 책임을 추가할 수 있다.
  • 재사용성이 향상된다.
  • 각 데코레이터는 하나의 책임을 관리하기 때문에 SRP(Single Responsibility Principle)를 준수한다.

Cons

  • 기본적으로 객체에 책임을 순차적으로 적용하기 때문에, 그 순서에 영향을 받는다.
Related Links