데코레이터 패턴


데코레이터 패턴을 사용하면 구조를 변경하지 않고도 기존 객체에 새로운 기능을 추가할 수 있습니다. 이러한 유형의 디자인 패턴은 기존 클래스를 감싸는 래퍼 역할을 하는 구조적 패턴입니다.

이 패턴은 클래스 메서드 시그니처의 무결성을 유지하면서 원래 클래스를 래핑하고 추가 기능을 제공하는 데코레이션 클래스를 만듭니다.

다음 예제를 통해 데코레이터 패턴의 사용을 보여줍니다. 그 중 도형 클래스를 변경하지 않고 다양한 색상으로 도형을 꾸며보겠습니다.

Introduction

의도: 객체에 몇 가지 추가 책임을 동적으로 추가합니다. 기능 추가 측면에서 데코레이터 패턴은 하위 클래스를 생성하는 것보다 더 유연합니다.

주요 솔루션: 일반적으로 상속을 사용하여 클래스를 확장하는 경우가 많습니다. 상속은 클래스에 정적 기능을 도입하고 확장 기능이 증가하면 하위 클래스도 확장되기 때문입니다.

사용 시기: 많은 하위 클래스를 추가하지 않고 클래스를 확장합니다.

해결 방법: 특정 기능적 책임을 나누고 데코레이터 패턴을 상속합니다.

키 코드: 1. Component 클래스는 추상적인 역할을 하며 구체적으로 구현하면 안 됩니다. 2. Component 클래스를 참조하고 상속하도록 클래스를 수정하고, 특히 상위 클래스 메서드를 재정의하도록 클래스를 확장합니다.

적용 예: 1. Sun Wukong은 "사원"이 되어도 기본적으로는 원숭이이지만 사원의 기능을 가지고 있습니다. 2. 그림은 액자 유무에 관계없이 벽에 걸 수 있지만, 일반적으로 액자가 있고 실제로는 액자가 벽에 걸려 있습니다. 벽에 걸기 전에 그림을 유약 처리하고 액자에 넣은 다음 그림, 유리 및 프레임이 하나의 개체를 형성합니다.

장점: 데코레이팅 클래스는 독립적으로 개발할 수 있으며 서로 결합되지 않습니다. 데코레이션 모드는 구현 클래스의 기능을 동적으로 확장할 수 있습니다.

단점: 다층 장식은 더 복잡합니다.

사용 시나리오: 1 클래스의 기능을 확장합니다. 2. 동적으로 기능을 추가하고 동적으로 취소합니다.

참고: 상속 대신 사용할 수 있습니다.

Implementation

Shape 인터페이스와 Shape 인터페이스를 구현하는 엔터티 클래스를 생성하겠습니다. 그런 다음 Shape 인터페이스를 구현하고 Shape 개체를 인스턴스 변수로 사용하는 추상 장식 클래스 ShapeDecorator를 만듭니다.

RedShapeDecoratorShapeDecorator를 구현하는 엔터티 클래스입니다.

DecoratorPatternDemo, 우리의 데모 수업은 RedShapeDecorator를 사용하여 Shape 개체를 장식합니다.

decorator_pattern_uml_diagram.jpg

1단계

인터페이스를 만듭니다.

Shape.java

public interface Shape {
   void draw();
}

2단계

인터페이스를 구현하는 엔터티 클래스를 만듭니다.

Rectangle.java

public class Rectangle implements Shape {

   @Override
   public void draw() {
      System.out.println("Shape: Rectangle");
   }
}

Circle.java

public class Circle implements Shape {

   @Override
   public void draw() {
      System.out.println("Shape: Circle");
   }
}

3단계

Shape 인터페이스를 구현하는 추상 장식 클래스를 만듭니다.

ShapeDecorator.java

public abstract class ShapeDecorator implements Shape {
   protected Shape decoratedShape;

   public ShapeDecorator(Shape decoratedShape){
      this.decoratedShape = decoratedShape;
   }

   public void draw(){
      decoratedShape.draw();
   }	
}

4단계

ShapeDecorator 클래스를 확장하는 엔터티 장식 클래스를 만듭니다.

RedShapeDecorator.java

public class RedShapeDecorator extends ShapeDecorator {

   public RedShapeDecorator(Shape decoratedShape) {
      super(decoratedShape);		
   }

   @Override
   public void draw() {
      decoratedShape.draw();	       
      setRedBorder(decoratedShape);
   }

   private void setRedBorder(Shape decoratedShape){
      System.out.println("Border Color: Red");
   }
}

5단계

RedShapeDecorator를 사용하여 Shape 개체를 장식합니다.

DecoratorPatternDemo.java

public class DecoratorPatternDemo {
   public static void main(String[] args) {

      Shape circle = new Circle();

      Shape redCircle = new RedShapeDecorator(new Circle());

      Shape redRectangle = new RedShapeDecorator(new Rectangle());
      System.out.println("Circle with normal border");
      circle.draw();

      System.out.println("\nCircle of red border");
      redCircle.draw();

      System.out.println("\nRectangle of red border");
      redRectangle.draw();
   }
}

6단계

출력을 확인합니다.

rreee