Day 10 – Decorator Pattern

데코레이터 패턴은 구조를 변경하지 않고도 객체에 새로운 기능을 동적으로 추가할 수 있는 구조적 디자인 패턴입니다. 이는 기존 클래스를 직접 수정하지 않고도 기존 클래스의 동작을 확장할 수 있는 유연한 방법을 제공합니다.


주요 구성

  • 구성 요소: 특정 작업을 수행할 수 있는 개체에 대한 인터페이스 또는 추상 클래스를 정의합니다. 추가 기능으로 향상시키려는 대상 개체를 나타냅니다.
  • ConcreteComponent: Component 인터페이스를 구현하는 실제 클래스입니다. 기본적인 기능을 제공합니다.
  • 데코레이터: 이는 Component 인터페이스를 구현하고 Component 객체에 대한 참조를 보유합니다. 원본 개체를 래핑하여 새로운 동작을 추가합니다.
  • ConcreteDecorator: Decorator 클래스를 확장하고 특정 기능이나 수정 사항을 추가합니다.

Code

일반 텍스트를 표시할 수 있는 간단한 문자 메시지 개체를 고려해 보겠습니다. 이제 이 메시지에 HTML 태그, 암호화 또는 네트워크 전송을 추가하려면 각 기능에 대해 별도의 데코레이터를 만들 수 있습니다. 필요에 따라 이러한 데코레이터를 결합하여 원본 메시지 개체를 향상시킬 수 있습니다.

IComponent.cs
// 'Component' interface
public interface IComponent
{
    string Operation();
}
C#
ConcreteComponent.cs

// 'ConcreteComponent' class
public class ConcreteComponent : IComponent
{
    public string Operation()
    {
        return "ConcreteComponent";
    }
}
C#
Decorator.cs

// 'Decorator' 추상 class
public abstract class Decorator : IComponent
{
    protected IComponent _component;

    public Decorator(IComponent component)
    {
        _component = component;
    }

    public virtual string Operation()
    {
        return _component.Operation();
    }
}
C#
ConcreteDecoratorA.cs

// 'ConcreteDecoratorA' class
public class ConcreteDecoratorA : Decorator
{
    public ConcreteDecoratorA(IComponent component) : base(component)
    {
    }

    public override string Operation()
    {
        return $"ConcreteDecoratorA({base.Operation()})";
    }
}
C#
ConcreteDecoratorB.cs

// 'ConcreteDecoratorB' class
public class ConcreteDecoratorB : Decorator
{
    public ConcreteDecoratorB(IComponent component) : base(component)
    {
    }

    public override string Operation()
    {
        return $"ConcreteDecoratorB({base.Operation()})";
    }
}
C#
Program.cs

// Create basic component
IComponent component = new ConcreteComponent();
Console.WriteLine("Basic Component: " + component.Operation());

// Decorated with A
IComponent decoratedComponentA = new ConcreteDecoratorA(component);
Console.WriteLine("Decorated with A: " + decoratedComponentA.Operation());

// Decorated with B
IComponent decoratedComponentB = new ConcreteDecoratorB(component);
Console.WriteLine("Decorated with B: " + decoratedComponentB.Operation());

// Decorated with A and B
IComponent decoratedComponentAB = new ConcreteDecoratorB(decoratedComponentA);
Console.WriteLine("Decorated with A and B: " + decoratedComponentAB.Operation());
C#

Results:


요약

데코레이터 패턴은 프로토타입을 사용하는 JavaScript와 같은 언어에서 특히 유용하며 C#과 같은 클래스 기반 언어에서도 디자인 유연성을 제공합니다. 이를 통해 특히 런타임에 기능을 추가하거나 수정해야 할 때 개체 기능을 동적으로 확장할 수 있습니다.

데코레이터 패턴의 장점

  • 기존 코드를 변경하지 않고 새로운 기능을 추가합니다.
  • 복잡한 기능을 위해 여러 데코레이터를 구성할 수 있습니다.
  • 상속보다 더 많은 유연성을 제공합니다.

단점

  • 다수의 작은 개체가 발생하여 시스템 복잡성이 증가할 수 있습니다.
  • 구성 요소와 데코레이터 간의 관계를 이해하는 것은 어려울 수 있습니다.

이러한 장단점을 고려하면 데코레이터 패턴은 객체 동작의 동적 확장이나 수정이 필요한 상황에 가장 적합합니다.

Links

Comments

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다