반응형
Design Pattern - Decorator
- 주어진 상황 및 용도에 따라 특정 객체에 책임을 덧붙이는 패턴입니다.
- 기능 확장이 필요한 경우 서브클래싱 대신 사용할 수 있습니다.
기본구조
- Decorator 패턴의 기본적인 구조입니다.
- Component : Component와 Decorator 측에서 구현할 인터페이스입니다.
- Decorator : Component를 상속하면서, 내부적으로 Component를 보유하고 있습니다.
- Concrete Component : Component를 구현한 구현체로, Decorate를 적용할 기본 객체입니다.
- Concrete Decorator : Decorator를 구현할 구현체입니다.
- 솔직히 아직까지는 단순한 상속과 뭐가 그렇게 다른건지 잘 와닿지 않습니다. 이를 Swift 코드로 작성하면서 이해해봅시다.
코드예제
protocol Component {
func operation()
}
class ConcreteComponent: Component {
func operation() {
print("Basic Operation")
}
}
- 먼저 기본 기능을 선언해놓은 Component와 이를 구현한 ConcreteComponent입니다.
- operation 메서드를 호출하면 "Basic Operation" 문자를 출력합니다.
protocol Decorator: Component {
var component: Component { get set }
}
class ConcreteDecoratorA: Decorator {
var component: Component
init(component: Component) {
self.component = component
}
func operation() {
component.operation()
print("A Operation")
}
}
class ConcreteDecoratorB: Decorator {
var component: Component
init(component: Component) {
self.component = component
}
func operation() {
component.operation()
print("B Operation")
}
}
class ConcreteDecoratorC: Decorator {
var component: Component
init(component: Component) {
self.component = component
}
func operation() {
component.operation()
print("C Operation")
}
}
- Decorator의 기능을 선언한 Decorator Protocol과 이를 구현한 ConcreteDecoratorA,B,C 입니다.
- Decorator는 내부에 Component를 들고 있고 이를 활용할 수 있습니다.
let basic = ConcreteComponent()
let a = ConcreteDecoratorA(component: basic)
let b = ConcreteDecoratorB(component: basic)
let c = ConcreteDecoratorC(component: basic)
a.operation()
/* Basic Operation
A Operation */
b.operation()
/* Basic Operation
B Operation */
c.operation()
/* Basic Operation
C Operation */
- 이제 이들을 Client에서 활용해봅시다.
- 기본적인 기능을 가진 ConcreteComponent 인스턴스를 생성하고, 이를 활용해 ConcreteDecoratorA,B,C 인스턴스를 생성해봅시다.
- 그리고 operation을 출력하면 Basic Operation과 각 Operation이 함께 출력됩니다.
- 여기까지는 매우 당연하게 느껴지죠? Decorator의 진짜 매력은 이 다음에 나옵니다.
let ab = ConcreteDecoratorB(component: a)
let abc = ConcreteDecoratorC(component: ab)
ab.operation()
/* Basic Operation
A Operation
B Operation */
abc.operation()
/* Basic Operation
A Operation
B Operation
C Operation */
- Decorator는 반복적으로 기능을 더할 수 있습니다.
- 기본 ConcreteComponent에 A를 더하고 B를 더할 수 있습니다.
- 여기서 멈추지 않고 C를 더하는 것도 가능합니다.
- 이렇게하면 다양한 조합의 타입(ConcreteDecoratorAB, ConcreteDecoratorAC, ConcreteDecoratorBC, ...)을 각각 생성하지 않고 조합을 통해 만들 수 있을 것입니다.
정리
- Decorator 패턴을 사용하면 객체의 기능을 동적으로 추가할 수 있겠네요. 객체의 단일책임원칙도 지킬 수 있구요.
- 하지만 이를 겹겹히 애워싸면서 객체를 구성하다보면 결국 객체의 정체를 제대로 파악할 수 없고, 스택과 같은 형태로 기능이 쌓이기 때문에 중간에 존재하는 특정 데코레이터를 삭제하는 것이 어렵습니다.
반응형
'🍎 Apple > Patterns' 카테고리의 다른 글
[iOS Design Pattern] Factory Method (0) | 2022.04.26 |
---|---|
[iOS Design Pattern] Coordinator (3) | 2022.04.12 |
[iOS Architecture] VIPER (0) | 2022.04.11 |
[iOS Architecture] MVC, MVP, MVVM (feat. Clean Architecture) (4) | 2022.01.30 |
Clean Architecture and Design - Robert C. Martin (엉클 밥) (2) | 2022.01.21 |