디자인패턴

데코레이터 패턴(Decorator Pattern)

ppp5500 2022. 4. 11. 14:19

데코레이터 패턴이란 주어진 상황 및 용도에 따라 어던 객체에 책임을 덧붙이는 패턴으로, 기능 확장이 필요할 때 서브클래싱 대시 쓸 수 있는 유연한 대안이 될 수 있다.

-위키백과(https://ko.wikipedia.org/wiki/%EB%8D%B0%EC%BD%94%EB%A0%88%EC%9D%B4%ED%84%B0_%ED%8C%A8%ED%84%B4)

Component: 기본 기능을 뜻하는 ConcreteComponent와 추가 기능을 뜻하는 Decorator의 공통 기능을 정의한다. 즉, 클라이언트는 Component를 통해 실제 객체를 사용한다.

ConcreteCompnent: 기본 기능을 구현하는 클래스

Decorator: 많은 수가 존재하는 구체적인 Decorator의 공통 기능을 제공한다.

ConcreteDecoratorA, ConcreteDecoratorB: Decorator의 하위 클래스로 기본 기능에 추가되는 개별적인 기능을 뜻한다.

 

 

Display road = new RoadDisplay();
road.draw();

Display roadWithLane = new LaneDecorator(new RoadDisplay());
roadWithLane.draw();

Display roadWithLaneAndTraffic = new LaneDecorator(new TrafficDecorator(new RoadDisplay()));
roadWithLaneAndTraffic.draw();

public abstract class Display
{
    public abstract void draw();
}

public class RoadDisplay :Display
{
    public override void draw()
    {
        Console.WriteLine("기본 도로 표시");
    }
}

public abstract class DisplayDecorator : Display
{
    private Display decoratedDisplay;

    public DisplayDecorator(Display decoratedDisplay)
    {
        this.decoratedDisplay = decoratedDisplay;
    }

    public override void draw()
    {
        decoratedDisplay.draw();
    }
}

public class LaneDecorator : DisplayDecorator
{
    public LaneDecorator(Display decoratedDisplay):base(decoratedDisplay)
    {

    }

    public override void draw()
    {
        base.draw(); //설정된 기본 표시 기능을 수행
        drawLane(); //추가적으로 차선을 표시
    }

    private void drawLane()
    {
        Console.WriteLine("\t차선 표시");
    }
}

public class TrafficDecorator: DisplayDecorator
{
    public TrafficDecorator(Display decoratorDisplay) : base(decoratorDisplay)
    {

    }

    public override void draw()
    {
        base.draw();
        ShowTraffic();
    }

    private void ShowTraffic()
    {
        Console.WriteLine("\t교통량 표시");
    }
}

실행 결과:

데코레이터 패턴을 이용하지 않고 각 기능들의 조합을 모두 구현한다면, 기능의 조합 별로 너무 많은 클래스가 생겨날 수 있다. 데코레이터 패턴은 조합별로 클래스를 구현할 필요 없이 각각의 기능들만 만들어 놓으면 조합이 가능하다.