인생을 코딩하다.

[Java] 디자인패턴(DesignPattern) - 데코레이터 패턴(Decorator Pattern) 본문

Java

[Java] 디자인패턴(DesignPattern) - 데코레이터 패턴(Decorator Pattern)

Hyung1 2020. 11. 12. 13:53
728x90
반응형

자바의 입출력 스트림은 데코레이터 패턴을 사용한다.

데코레이터 패턴이란?

  • 실제 입출력기능을 가진 객체(컴포넌트)와 그 외 다양한 기능을 제공하는 데코레이터(보조스트림)을 사용하여 다양한 입출력 기능을 구현한다.
  • 상속보다 유연한 확장성을 가진다.
  • 지속적인 서비스의 증가와 제거가 용이하다.

 

ConcreteComponent 실질적으로 기반이 되는 클래스(입 출력 관련)

Decorator 기능을 제공해주는 클래스

위 2개의 클래스는 같은 클래스로부터 상속을 받는다.

 

Decorator는 혼자 돌아갈 수가 없다. 그래서 항상 다른 Component를 가지고 있다. 이 Component는 또다른 Decorator일 수도 있고, 기반 클래스 일수도 있다. Decorator의 종류는 여러가지 일 수도 있다. 그래서 이 기능들이 다 보조 기능 일 수도 있다. 본인이 보조적으로 하는 기능, 원래 해야하는 기능 등

 

위 그림만 보고는 이해하기가 힘들다. 데코레이터 패턴을 활용하여 커피 예제를 만들어보며 데코레이터 패턴을 이해해보도록 하자.

 

아메리카노

라떼 = 아메리카노 + 우유

모카커피 = 아메리카노 + 우유 + 모카시럽

Whipping cream 모카 커피 = 아메리카노 + 우유 + 모카시럽 + whipping cream

 

데코레이터를 어떻게 붓냐에 따라서 각각 다른 커피가 만들어진다.

아메리카노에 우유를 넣으면 라떼, 모카시럽까지 섞으면 모카커피가 된다.

 

Coffee.java

CoffeeTest.java

Decorator.java

EtiopiaAmerivano.java

package DesignPattern.decorator;

public class EtiopiaAmericano extends Coffee{

    // 오리지널 컴포넌트
    @Override
    public void brewing() {
        System.out.print("EtiopiaAmericano");
    }
}

KenyAmericano.java

package DesignPattern.decorator;

public class KenyaAmericano extends Coffee{

    @Override
    public void brewing() {
        System.out.print("KenyaAmericano");

    }
}

Latte.java

package DesignPattern.decorator;

public class Latte extends Decorator{

   public Latte(Coffee coffee) {
        super(coffee);
    }

    // 제조 (상위클래스의 제조하는 법을 한 번 호출한후에, 커피를 만든다.
    public void brewing() {
       super.brewing();
       System.out.print(" Adding Milk");
    }
}

Mocha.java

package DesignPattern.decorator;

public class Mocha extends Decorator{

    public Mocha(Coffee coffee) {
        super(coffee);
    }

    // 제조 (상위클래스의 제조하는 법을 한 번 호출한후에, 커피를 만든다.
    public void brewing() {
        super.brewing();
        System.out.print(" Adding Mocha Syrup");
    }
}

출력 결과

 

데코레이터 패턴의 중요 포인트를 짚어보자. 반환 값에 장식을 더한다는 것을 뺴면 프록시 패턴과 동일하다.

  • 장식자는 실제 서비스와 같은 이름의 메서드를 구현한다. 이때 인터페이스를 사용한다.
  • 장식자는 실제 서비스에 대한 참조 변수를 갖는다.
  • 장식자는 실제 서비스와 같은 이름을 가진 메서드를 호출하고, 그 반환값에 장식을 더해 클라이언트에게 돌려준다.
  • 장식자는 실제 서비스의 메서드 호출 전후에 별도의 로직을 수행할 수도 있다.

장식자라는 이름에서 느껴지듯 실제 서비스의 반환 값을 예쁘게? 포장(장식)하는 패턴이 데코레이터 패턴임을 기억하자.  마지막으로 데코레이턴 패턴을 정리하면 다음과 같다.

"메서드 호출의 반환값에 변화를 주기 위해 중간에 장식자를 두는 패턴"

 

데코레이터 패턴이 프록시 패턴과 동일한 구조를 갖기에 데코레이터 패턴도 개방 폐쇄 원칙(OCP)와 의존 역전 원칙(DIP)이 적용된 설계 패턴임을 알 수 있다.

728x90
반응형
Comments