ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [디자인패턴] 데코레이터 패턴
    IT 발자취.../디자인패턴 2018. 12. 9. 03:13

    . 정의
    객체에 추가적인 요건을 동적으로 첨가한다.
    데코레이터는 서브클래스를 만드는 것을 통해서 기능을 유연하게 확장할 수 있는 방법을 제공한다.

    <<데코레이터 패턴 클래스 다이어그램>>

    ConcreteComponent에 새로운 행동을 동적으로 추가할 수 있다.
    각 데코레이터 안에는 구성요소(Component)에 대한 레퍼런스가 들어있는 인스턴스 변수가 있다.
    Decorator는 자신이 장식할 구성요소(Component)와 같은 인터페이스 또는 추상 클래스를 구현한다.
    ConcreteDecoratorA, ConcreteDecoratorB 에는 그 객체가 장식하고 있는(데코레이터가 감싸고있는 Component객체)을 위한 인스턴스 변수가 있다. 따라서 데코레이터 Component의 상태를 확장할 수 있다.
    ConcreteDecoratorA, ConcreteDecoratorB 데코레이터에서 새로운 메소드를 추가할 수도 있다. 하지만 일반적으로 새로운 메소드를 추가하는 대신 Component에 원래 있던 메소드를 호출하기 전, 또는 후에 별도의 작업을 처리하는 방식으로 새로운 기능을 추가한다.

    2. 개요
    참고 : http://jusungpark.tistory.com/9

    3. 해결
    디자인 원칙
    OCP(Open-Closed principle)
    클래스는 확장에 대해서는 열려있어야하지만 코드 변경에 대해서는 닫혀 있어야 한다.

    기존의 코드는 건드리지 않은 채로 확장을 통해서 새로운 행동을 간단하게 추가할 수  있는 데코레이터 패턴을 사용해보기로 한다.

    상속을 써서 음료 가격과 첨가물 가격을 합한 총 가격을 계산하는 방법은 그리 좋은 방법이 되지 못한다.
    클래스가 많아지거나 일부 서브 클래스에는 적합하지 않은 기능을 클래스에 추가하게 되는 문제가 있었다.
    우선 특정 음료에서 시작해서 첨가물로 그 음료를 장식해본다.
    1. DarkRoast 객체를 가져온다.
    2. Mocha 객체로 장식한다.
    3. Whip 객체로 장식한다.
    4. cost() 메소드를 호출한다. 이때 첨가물의 가격을 계산하는 일은 해당 객체들에게 위임된다.

    새로 디자인한 Beverage 클래스

    디자인을 바탕으로 코드를 만들어 보겠습니다.

    //Component public abstract class Beverage { protected String description = "Empty"; public String getDescription() { return this.description; } public abstract int cost(); } //Decorator public abstract class CondimentDecorator extends Beverage { public abstract String getDescription(); }
    //ConcreteComponent public class DarkRoast extends Beverage{ public DarkRoast() { this.description = "DarkRoast"; } @Override public int cost() { return 4000; } } public class Espresso extends Beverage { public Espresso() { this.description = "Espresso"; } @Override public int cost() { return 3500; } }
    //ConcreteDecoratorA public class Mocha extends CondimentDecorator{ private Beverage beverage; public Mocha(Beverage beverage) { this.beverage = beverage; } @Override public String getDescription() { return beverage.getDescription() + "Mocha"; } @Override public int cost() { return 500 + beverage.cost(); } }
    public static void main(String[] args) { Beverage beverage = new Espresso(); System.out.println(beverage.getDescription() + " cost : "+beverage.cost()); //DarkRoast Beverage beverage1 = new DarkRoast(); beverage1 = new Mocha(beverage1); beverage1 = new Mocha(beverage1); beverage1 = new Whip(beverage1); System.out.println(beverage1.getDescription() + " cost : "+beverage1.cost()); //HouseBlend Beverage beverage2 = new HouseBlend(); beverage2 = new Mocha(beverage2); beverage2 = new Whip(beverage2); System.out.println(beverage2.getDescription() + " cost : "+beverage2.cost()); } /* *결과 *Espresso cost : 3500 *DarkRoastMochaMochaWhip cost : 6000 *HouseBlendMochaWhip cost : 3500 */

    데코레이터가 적용된 예 : 자바 I/O

    'IT 발자취... > 디자인패턴' 카테고리의 다른 글

    [디자인패턴]싱글턴 패턴  (0) 2018.12.09
    [디자인패턴]팩토리 패턴  (0) 2018.12.09

    댓글

Designed by Gintire