STUDY/Design Pattern

장식자 패턴(Decorator Pattern)

디리릭 2022. 12. 15. 00:21
728x90

장식자 패턴은 객체의 결합을 통해 기능을 동적으로 유연하게 확장 할 수 있게 해주는 패턴이다. 즉, 기능 확장이 필요할 때 서브 클래스 대신 사용할 수 있다.

기본기능과 장식 기능을 하는 클래스를 따로 정의하여 동적인 기능을 장식 기능 클래스 쪽에 구현을 한다. 그리하여 다량의 서브클래스를 생성하는 것을 막을 수 있다.

객체의 타입과 호출 가능한 메소드를 그대로 유지하면서 객체에 새로운 책임을 추가할 때, 유연한 책임을 정의할 때 사용한다.

구조

▷ Component: 기본적인 기능과 장식의 기능의 베이스가 되는 인터페이스.

▷ConcreteComponent: 기본적인 기능을 구현한 클래스

▷Decorator: ConcreteComponent와 동일한 인터페이스를 상속받으므로서 Decorator 타입이여도 ConcreteComponent의 메소드를 사용할 수 있어야 한다. 이를 통해 기본 기능 클래스의 코드를 수정하지 않아도 기능을 추가할 수 있다.

▷ConcreteDecorator: 추가되는 기능에 대한 클래스

구현

  public abstract class Beverage
    {
        protected string description = "제목없음";
        private BeverageSize size;

        public virtual string getDescription() 
        {
            return description;
        }
        public abstract double Cost();
        public void setSize(BeverageSize size) 
        {
            this.size = size;
        }
        public BeverageSize getSize() 
        {
            return this.size;
        }
    }
   public class Americano : Beverage
    {
        public Americano(BeverageSize bSize) 
        {
            description = "아메리카노";
            setSize(bSize);
        }
        public override double Cost()
        {
            return 1.99;
        }
    }
 public abstract class Decorator : Beverage
    {
        //기능을 추가 가능
    }
 public class Shot : Decorator
    {
        Beverage beverage;
        public Shot(Beverage beverage) 
        {
            this.beverage = beverage;
        }
        public override double Cost()
        {
            double cost = beverage.Cost();
            if (getSize() == BeverageSize.TALL) cost += 0.20;
            else if (getSize() == BeverageSize.GRAND) cost += 0.25;
            else if (getSize() == BeverageSize.VENTI) cost += 0.30;

            return cost;
        }

        public override string getDescription()
        {
            return beverage.getDescription() + ", 샷추가";
        }
    }
   class Program
    {
        static void Main(string[] args)
        {
            Beverage coffee = new Americano(BeverageSize.TALL);
            coffee = new Shot(coffee);
            coffee = new Shot(coffee);

            Console.WriteLine($"주문하신 메뉴 확인해주세요 -> \n메뉴: {coffee.getDescription()}");
            Console.WriteLine($"가격: {coffee.Cost()}");

            Console.ReadLine();
        }
    }

>>RESULT)

이 패턴의 단점은 많은 ConcreteDecorator가 생성된다는 것이다.

구조적인 확장에 용이하다.

-> 조합을 할 수 있다는 점

WPF의 트리거, 스타일과 유사해~~~

728x90

'STUDY > Design Pattern' 카테고리의 다른 글

옵저버 패턴(Observer Pattern)  (0) 2022.12.19
퍼사드 패턴(Facade Pattern)  (0) 2022.12.15
복합체 패턴(Composite Pattern)  (0) 2022.11.27
브릿지 패턴(Bridge Pattern)  (0) 2022.11.27
어댑터 패턴 (Adapter pattern)  (0) 2022.11.27