데코레이터 패턴(Decorator Pattern)

Jimin·2022년 8월 18일
0

JAVA

목록 보기
13/23

데코레이터 패턴이란?

  • 주어진 상황 및 용도에 따라 어떤 객체에 책임(기능)을 동적으로 추가하는 패턴
  • 기본 기능을 가지고 있는 클래스를 하나 만들어주고 추가할 수 있는 기능들을 추가하기 편하도록 설계하는 방식

  • component: 실질적인 인스턴스를 컨트롤 하는 역할
  • ConcreteComponent: Component의 실질적인 인스턴스의 부분으로 책임의 주체의 역할
  • Decorator: Component와 ConcreteDecorator를 동일시 하도록 해주는 역할
  • ConcreteDecorator: 실질적인 장식 인스턴스 및 정의로, 추가된 책임의 추체

데코레이터 패턴의 장단점

장점

  1. 기존 코드를 수정하지 않고도 데코레이터 패턴을 통해 행동을 확장시킬 수 있다.
  2. 구성과 위임을 통해서 실행중인 새로운 행동을 추가할 수 있다.

단점

  1. 의미 없는 객체들이 너무 많이 추가될 수 있다.
  2. 데코레이터를 너무 많이 사용하면 코드가 필요 이상으로 복잡해질 수 있다.

데코레이터를 사용하면 좋은 상황

  1. 클래스의 요소들을 계속해서 수정하면서 사용하는 구조가 필요한 경우
  2. 여러 요소들을 조합해서 사용하는 클래스 구조인 경우
  • 위와 같은 상황의 예시
    ⇒ 커피 제조 → 다양한 재료들의 구성으로 하나의 커피가 완성된다.
    • 에스프레소: 에스프레소
    • 아메리카노: 에스프레소 + 물
    • 카페라떼: 에스프레소 + 물 + 우유
      ...

위의 재료들을 모두 클래스로 구현한다면 너무 많은 클래스를 구현해주어야 한다.
→ 비효율적(커피의 종류가 많을 수록 더 비효율적임)


데코레이터 패턴 사용 예제

Component interface

  • 재료들을 추가해주는 함수 구현
public interface Component {
    String add(); //재료 추가
}

BaseComponent class

  • Component interface를 구현
  • 커피의 기본재료인 에스프레소 리턴
public class BaseComponent implements Component {

    @Override
    public String add() {
        // TODO Auto-generated method stub
        return "에스프레소";
    }
}

Decorator class

  • Component interface를 구현
  • 커피 재료들의 근간이 되는 추상 클래스
  • 재료들은 이 Decorator class를 상속 받아서 재료를 추가한다.
abstract public class Decorator implements Component {
    private Component coffeeComponent;
    
    public Decorator(Component coffeeComponent) {
        this.coffeeComponent = coffeeComponent;
    }
    
    public String add() {
        return coffeeComponent.add();
    }
}

WaterDecorator class

  • 물 추가 클래스
  • Decorator 클래스 상속
//물을 추가해주는 클래스
public class WaterDecorator extends Decorator {
    public WaterDecorator(Component coffeeComponent) {
        super(coffeeComponent);
    }
    
    @Override
    public String add() {
        // TODO Auto-generated method stub
        return super.add() + " + 물";
    }
}

MilkDecorator class

  • 우유 추가 클래스
  • Decorator 클래스 상속
//우유를 추가해주는 클래스
public class MilkDecorator extends Decorator {
    public MilkDecorator(Component coffeeComponent) {
        super(coffeeComponent);
    }
    
    @Override
    public String add() {
        // TODO Auto-generated method stub
        return super.add() + " + 우유";
    }
}

Main class

  • 에스프레소: 에스프레소
  • 아메리카노: 에스프레소 + 물
  • 카페라떼: 에스프레소 + 물 + 우유
public class Main {

    public static void main(String[] args) {
        Component espresso = new BaseComponent();
        System.out.println("에스프레소 : " + espresso.add());
        
        Component americano = new WaterDecorator(new BaseComponent());
        System.out.println("아메리카노 : " + americano.add());
        
        Component latte = new MilkDecorator(new WaterDecorator(new BaseComponent()));
        System.out.println("라떼 : " + latte.add());
    }
}

출처

https://coding-factory.tistory.com/713

profile
https://github.com/Dingadung

0개의 댓글