ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [C#] Decorator Pattern
    프로그래밍/Design Pattern 2020. 11. 6. 13:47

     Decorator Pattern

     데코레이터 패턴이란 객체의 결합을 통해 기능을 동적으로 유연하게 확장 할 수 있도록 해주는 패턴이다.

    , 기본 기능에 추가할 수 있는 기능의 종류가 많은 경우에 각 추가 기능을 Decorator 클래스로 정의 한 후 필요한 Decorator 객체를 조합함으로써 추가 기능의 조합을 설계 하는 방식이다.

     

     

     

     

     

     

    커피를 예로 들어보자. 커피에는 카페라떼, 에스프레소, 돌체라떼 등등 수많은 종류가 있다. 커피 가격을 계산하는 프로그램을 만들려고 할때, 모든 종류의 커피객체를 만드는 것은 매우 비효율적이다. 이러한 경우에 사용하는 것이 바로 데코레이터 패턴이다.

     

    커피는 종류는 다양하지만 결국 원두에 어떤 첨가물을 넣느냐에 차이다. 이때 우리는 원두를 Component, 첨가물을 Decorator 로 설정할 수 있다.

     

     

     

     

    원두와 첨가물은 모두 Beverage 를 상속받는다. 원두는 Beverage 구조를 상속받아 클래스를 바로 구현고, 첨가물은 구조를 상속받아 Decorator 를 구현할 수 있는 새로운 구조를 만들었다. 이렇게 해주어야 두 클래스의 뿌리가 같기 때문에 데코레이션이 가능하게 된다.

     

    CondimentDecorator 클래스를 보면 Beverage 클래스 방향으로 화살표가 하나 있다. 이건 데코레이터 클래스 내부에 Beverage 객체를 담을 수 있는 변수가 있기 때문이다.

     

    그림으로 보면 데코레이터 패턴이 어떻게 작동되는지 쉽게 알 수 있다.

     

     

     

     

     

    이런식으로 첨가물들이 원두를 감싸는 방식으로 작동을 하게되고 감싸는 횟수에는 제한이 없다. 하지만, 너무 여러번 데코레이션 작업을 하게되면 작업물이 지저분해지고 한눈에 알아보기 힘들게 된다. 이부분은 코드를 보시면 이해가 될것이다.

     

     

     

     예제 코드

     

    using System;
    using System.Runtime.InteropServices.WindowsRuntime;
    using System.Runtime.Intrinsics.X86;
    using System.Xml.Serialization;
    
    namespace ConsoleApp2
    {
        class Program
        {
            static void Main(string[] args)
            {
                Beverage espresso = new Espresso();
                Beverage cafeMocha = new Milk(new Mocha(espresso));           
    
                Console.WriteLine("가격 : " + cafeMocha.Cost());
                Console.WriteLine("성분 : " + cafeMocha.GetDescription());
    
            }
        }
    
    
        public abstract class Beverage
        {
            protected string _description = string.Empty;
            public virtual string GetDescription()
            {
                return _description;
            }
            public abstract double Cost();
    
        }
    
    
    
        public class Espresso : Beverage
        {
            
            public Espresso()
            {
                _description = "Espresso";
            }
    
            public override double Cost()
            {
                return 1.2;
            }
    
    
        }
    
        public abstract class Decorator : Beverage
        {
            public abstract override string GetDescription();
        }
    
    
        public class Milk : Beverage
        {
            private Beverage _beverage;
    
            public Milk(Beverage beverage)
            {
                this._beverage = beverage;
            }
    
            public override double Cost()
            {
                return _beverage.Cost() + 0.3;
            }
    
            public override string GetDescription()
            {
                return _beverage.GetDescription() + " + Milk";
            }
        }
    
        public class Mocha : Decorator
        {
            private Beverage _beverage;
    
            public Mocha(Beverage _beverage)
            {
                this._beverage = _beverage;
            }
    
            public override double Cost()
            {
                return _beverage.Cost() + 0.20;
    
            }
    
            public override string GetDescription()
            {
                return _beverage.GetDescription() + " + 모카";
            }
        }
    
        
    
    }
    

     

    '프로그래밍 > Design Pattern' 카테고리의 다른 글

    [C#] Observer Pattern  (0) 2020.10.30
    [C#] Strategy Pattern  (0) 2020.10.23

    댓글

Designed by Tistory.