Workspace/Design Pattern
데코레이터 패턴 (Decorator Pattern): 유연한 기능 확장의 비밀
Bombus
2025. 1. 22. 12:13
1. 개요
디자인 패턴 중 Decorator 패턴은 기존 객체에 새로운 기능을 동적으로 추가하고 싶을 때 유용한 패턴입니다. 상속 없이도 객체의 행동을 확장할 수 있어, 코드 재사용성과 유지보수성을 높이는 데 탁월합니다. 🎯
2. 개념
Decorator 패턴은 객체를 감싸는(wrapper) 방식으로 동작합니다. 핵심 아이디어는 기존 객체를 수정하지 않고도 새로운 책임을 부여할 수 있다는 점입니다.
구조
- Component: 기본 인터페이스 또는 추상 클래스
- ConcreteComponent: 실제 기능을 구현한 클래스
- Decorator: Component를 확장할 추상 클래스
ConcreteDecorator: 구체적인 기능 확장을 구현한 클래스
3. 예제
C#에서의 간단한 예제로, 커피에 첨가물을 추가하는 시뮬레이션을 만들어보겠습니다. ☕
// Component
public interface ICoffee
{
string GetDescription();
double GetCost();
}
// ConcreteComponent
public class SimpleCoffee : ICoffee
{
public string GetDescription() => "Simple Coffee";
public double GetCost() => 2.0;
}
// Decorator
public abstract class CoffeeDecorator : ICoffee
{
protected ICoffee _coffee;
public CoffeeDecorator(ICoffee coffee)
{
_coffee = coffee;
}
public virtual string GetDescription() => _coffee.GetDescription();
public virtual double GetCost() => _coffee.GetCost();
}
// ConcreteDecorator
public class MilkDecorator : CoffeeDecorator
{
public MilkDecorator(ICoffee coffee) : base(coffee) { }
public override string GetDescription() => base.GetDescription() + ", Milk";
public override double GetCost() => base.GetCost() + 0.5;
}
public class SugarDecorator : CoffeeDecorator
{
public SugarDecorator(ICoffee coffee) : base(coffee) { }
public override string GetDescription() => base.GetDescription() + ", Sugar";
public override double GetCost() => base.GetCost() + 0.2;
}
// Usage
class Program
{
static void Main(string[] args)
{
ICoffee coffee = new SimpleCoffee();
Console.WriteLine($"{coffee.GetDescription()} : ${coffee.GetCost()}");
coffee = new MilkDecorator(coffee);
Console.WriteLine($"{coffee.GetDescription()} : ${coffee.GetCost()}");
coffee = new SugarDecorator(coffee);
Console.WriteLine($"{coffee.GetDescription()} : ${coffee.GetCost()}");
}
}
실행 결과
Simple Coffee : $2.0
Simple Coffee, Milk : $2.5
Simple Coffee, Milk, Sugar : $2.7
4. 장점과 주의점 🛠️
장점
- 유연성: 객체의 기능을 런타임에 동적으로 확장 가능.
- 조합 가능성: 다양한 Decorator를 조합해 새로운 기능 생성.
- OCP(Open/Closed Principle): 기존 코드를 변경하지 않고 기능 추가 가능.
주의점
- 많은 클래스: Decorator와 ConcreteDecorator가 많아질 경우 복잡도가 증가.
- 디버깅 어려움: 래핑된 구조로 인해 디버깅이 다소 까다로울 수 있음.
5. 결론
Decorator 패턴은 객체 지향 설계의 유연성을 극대화하는 강력한 도구입니다. 기존 객체를 수정하지 않고 기능을 확장해야 하는 상황에서 매우 유용하며, 특히 계층적 상속의 한계를 극복하는 데 도움을 줍니다. 다만, 과도한 사용은 복잡도를 높일 수 있으니 신중히 활용해야 합니다. ✅
6. 관련 링크
반응형