[swift] Decorator 디자인 패턴

Decorator 디자인 패턴은 객체에 새로운 기능을 동적으로 추가하기 위한 패턴입니다. 이 패턴은 상속을 사용하지 않고 객체에 추가적인 책임을 부여하는 방법을 제공하여 객체의 유연성을 높입니다.

Decorator 패턴 구성 요소

Decorator 디자인 패턴은 크게 다음과 같은 구성 요소로 이루어져 있습니다.

  1. Component(요소): 기본 기능을 정의하는 인터페이스 또는 추상 클래스입니다.
  2. ConcreteComponent(구체적 요소): Component에 정의된 기본 기능을 구현하는 클래스입니다.
  3. Decorator(장식자): Component와 동일한 인터페이스를 갖고 있으며, ConcreteComponent 객체에 추가적인 기능을 부여하기 위한 기반 클래스입니다.
  4. ConcreteDecorator(구체적 장식자): Decorator를 상속하고, 추가적인 기능을 구현하는 클래스입니다.

Decorator 패턴의 장점

Decorator 패턴을 사용하면 객체의 기능을 동적으로 확장시킬 수 있습니다. 또한, 상속을 사용하지 않기 때문에 객체 간의 결합도가 낮아져 유연성이 높아집니다.

Decorator 패턴의 예시

다음은 Swift언어를 사용하여 Decorator 패턴을 구현한 예시입니다.

// Component(요소) 인터페이스
protocol Coffee {
    func cost() -> Double
    func ingredients() -> String
}

// ConcreteComponent(구체적 요소)
class SimpleCoffee: Coffee {
    func cost() -> Double {
        return 1.0
    }

    func ingredients() -> String {
        return "커피"
    }
}

// Decorator(장식자) 클래스
class CoffeeDecorator: Coffee {
    let decoratedCoffee: Coffee

    init(decoratedCoffee: Coffee) {
        self.decoratedCoffee = decoratedCoffee
    }

    func cost() -> Double {
        return decoratedCoffee.cost()
    }

    func ingredients() -> String {
        return decoratedCoffee.ingredients()
    }
}

// ConcreteDecorator(구체적 장식자) 클래스
class MilkDecorator: CoffeeDecorator {
    override func cost() -> Double {
        return super.cost() + 0.5
    }

    override func ingredients() -> String {
        return super.ingredients() + ", 우유"
    }
}

// 사용 예시
let myCoffee: Coffee = MilkDecorator(decoratedCoffee: SimpleCoffee())
print("가격: \(myCoffee.cost()), 성분: \(myCoffee.ingredients())")

위 예시에서는 커피에 우유를 추가하는 Decorator 패턴을 구현하였습니다.

결론

Decorator 디자인 패턴은 객체에 동적으로 기능을 추가하기 위한 유용한 패턴으로, 유연하고 확장 가능한 객체를 설계하는 데 도움을 줍니다.

참고문헌

  1. Decorator Pattern - Wikipedia
  2. Head First Design Patterns, by Eric Freeman and Elisabeth Robson