Decorator (Wrapper)
- 객체들을 새로운 행동들을 포함한 특수 래퍼 객체들 내에 넣어서 위 행동들을 해당 객체들에 연결시킴
- 상속 대신 집합 관계 또는 합성을 사용함
- 래퍼는 일부 대상 객체와 연결할 수 있는 객체임
- 래핑된 객체와 같은 인터페이스 구현
- 민감한 데이터를 해당 데이터를 실제 사용하는 코드와 별도로 압축하고 암호화할 수 있음
- 객체들을 사용하는 코드를 훼손하지 않으면서 런타임에 추가 행동들을 객체들에 할당할 수 있을 때 사용
- final 키워드가 있어서 상속을 이용한 클래스 확장이 되지 않을 때 사용 가능
- 어댑터는 기존 객체의 인터페이스 변경,
데코레이터는 객체를 해당 객체의 인터페이스를 변경하지 않고 향상, 재귀적 합성 지원
- 어댑터는 다른 인터페이스, 프록시는 같은 인터페이스, 데코레이터는 향상된 인터페이스를 래핑된 객체에 제공
- 프록시는 보통 자체적으로 자신의 서비스 객체의 수명 주기를 관리,
데코레이터의 합성은 항상 클라이언트에 의해 제어됨
- 예시
/**
* The base Component interface defines operations that can be altered by
* decorators.
*/
interface Component {
operation(): string;
}
/**
* Concrete Components provide default implementations of the operations. There
* might be several variations of these classes.
*/
class ConcreteComponent implements Component {
public operation(): string {
return 'ConcreteComponent';
}
}
/**
* The base Decorator class follows the same interface as the other components.
* The primary purpose of this class is to define the wrapping interface for all
* concrete decorators. The default implementation of the wrapping code might
* include a field for storing a wrapped component and the means to initialize
* it.
*/
class Decorator implements Component {
protected component: Component;
constructor(component: Component) {
this.component = component;
}
/**
* The Decorator delegates all work to the wrapped component.
*/
public operation(): string {
return this.component.operation();
}
}
/**
* Concrete Decorators call the wrapped object and alter its result in some way.
*/
class ConcreteDecoratorA extends Decorator {
/**
* Decorators may call parent implementation of the operation, instead of
* calling the wrapped object directly. This approach simplifies extension
* of decorator classes.
*/
public operation(): string {
return `ConcreteDecoratorA(${super.operation()})`;
}
}
/**
* Decorators can execute their behavior either before or after the call to a
* wrapped object.
*/
class ConcreteDecoratorB extends Decorator {
public operation(): string {
return `ConcreteDecoratorB(${super.operation()})`;
}
}
/**
* The client code works with all objects using the Component interface. This
* way it can stay independent of the concrete classes of components it works
* with.
*/
function clientCode(component: Component) {
// ...
console.log(`RESULT: ${component.operation()}`);
// ...
}
/**
* This way the client code can support both simple components...
*/
const simple = new ConcreteComponent();
console.log("Client: I've got a simple component:");
clientCode(simple);
console.log('');
/**
* ...as well as decorated ones.
*
* Note how decorators can wrap not only simple components but the other
* decorators as well.
*/
const decorator1 = new ConcreteDecoratorA(simple);
const decorator2 = new ConcreteDecoratorB(decorator1);
console.log("Client: Now I've got a decorated component:");
clientCode(decorator2);
- 활용
반응형
'Personal-Study > Design Patterns' 카테고리의 다른 글
[TS Design Patterns] 구조 패턴 - 플라이웨이트 (0) | 2023.10.30 |
---|---|
[TS Design Patterns] 구조 패턴 - 퍼사드 (0) | 2023.10.28 |
[TS Design Patterns] 구조 패턴 - 프록시 (2) | 2023.10.26 |
[TS Design Patterns] 구조 패턴 - 컴포지트 (0) | 2023.10.24 |
[TS Design Patterns] 구조 패턴 - 브리지 (0) | 2023.10.23 |
댓글