본문 바로가기

Design Pattern

[Design Pattern] 18. Decorator Pattern(데코레이터 패턴) C#

728x90

객체의 계층 구조를 표현하고 개별 객체와 객체 그룹을 균일하게 처리해야 하는 상황을 도와주는 패턴입니다

새로운 행동들을 포함한 특수 래퍼 객체들 내에 넣어서 위 행동들을 해당 객체들에 연결시키는 구조적 디자인 패턴

 

구조 패턴(Structural Design Patterns)중 하나이죠.

 

장점

  • 객체를 여러 데코레이터로 래핑하여 여러 행동들을 합성할 수 있습니다.
  • 실행 중 객체들에서부터 책임들을 추가하거나 제거할 수 있습니다.
  • 새 자식 클래스를 만들지 않고도 객체의 행동을 확장할 수 있습니다.
  • 단일 책임 원칙을 만족하며 다양한 행동들의 여러 변형들을 구현하는 모놀리식 클래스를 여러 개의 작은 클래스들로 나눌 수 있습니다.

단점

  • 계층들의 초기 설정 코드가 보기 힘들 수 있습니다.
  • 데코레이터의 행동이 데코레이터 스택 내의 순서에 의존하지 않는 방식으로 데코레이터를 구현하기가 어렵습니다.
  • 래퍼들의 스택에서 특정 래퍼를 제거하기가 어렵습니다.

 

C#으로 Console 프로젝트를 하나 생성해서 할 것입니다.

 

목표는 Circle에 Color를 입히겠습니다.

 

프로젝트의 tree구조는 아래와 같습니다.

Composite (Project)

|- Program.cs (Main)

|- IShape.cs (Component interface)

|- Circle.cs (Concrete component class)

|- ShapeDecorator.cs (Decorator abstract class)

|- ColorDecorator.cs (Concrete decorator class)

 

 

 

IShape.cs

namespace Decorate
{
    public interface IShape
    {
        void Draw();
    }
}

Draw를 구성해줍니다.


Circle.cs

using System;

namespace Decorate
{
    public class Circle : IShape
    {
        public void Draw()
        {
            Console.WriteLine("Drawing circle");
        }
    }
}

원을 그릴수 있도록 구현해줍니다.


ShapeDecorator.cs

namespace Decorate
{
    public abstract class ShapeDecorator : IShape
    {
        protected IShape _shape;

        public ShapeDecorator(IShape shape)
        {
            _shape = shape;
        }

        public virtual void Draw()
        {
            _shape.Draw();
        }
    }


}

ShapeDecorator로 IShape을 가지고 Draw할 수 있게 만들어줍니다.


ColorDecorator.cs

using System;

namespace Decorate
{
    public class ColorDecorator : ShapeDecorator
    {
        public string color { get; set; } = "Red";
        public ColorDecorator(IShape shape, string color) : base(shape)
        {
            this.color = color;
        }

        public override void Draw()
        {
            _shape.Draw();
            Console.WriteLine($"Applying {color} color");
        }
    }
}

색을 입혀 그릴 수 있도록 color를 생성자에서 받아오고 색을 입혀 그리도록 Draw를 수정해줍니다.


Program.cs

namespace Decorate
{
    class Program
    {
        static void Main(string[] args)
        {
            IShape circle = new Circle();
            IShape colorCircle = new ColorDecorator(circle, "Blue");
            colorCircle.Draw();
        }
    }
}

Circle을 만든 뒤 ColorDecorator에 입힐 색과 함께 넣어주고 그려줍니다.

원하는 대로 원을 그리고 파란색을 추가한 것을 확인 할 수 있습니다.

실행 결과

 

이로써 구조패턴도 끝이 난거 같습니다.

다음부턴 생성 패턴에 대해 쓸 것 같습니다.