Free Lines Arrow
본문 바로가기
Design pattern/GoF(HeadFirst)

[HeadFirst] 데코레이터 패턴

by skahn1215 2023. 1. 7.
728x90
반응형

정의

  • 데코레이터 패턴으로 객체에 추가 요소를 동적으로 더한다.
  • 데코레이터를 사용하면 서브클래스를 만들 때 보다 훨씬 유연하게 기능을 확장할 수 있다.
  • 너무 많은 종류가 있을때 상속을 쓰게 되면 관리해야 될 객체가 많아진다.
    - 예를 들어 음료의 종류가 100개가 넘는다면 100개의 객체를 관리를 해야 될 것 이다.

  • 그렇기 때문에 데코레이터 패턴을 사용하면 된다.
  • 아래는 다크로스트 -> 모카추가 -> 휘핑크림을 추가한 데코레이터 패턴의 모습이다.

 

 

구조

기본구조

 

ConcreateComponent

  • component 의 구체화 
  • 메소드를 추가해 새로운 행동을 추가 할수 있다.

ConcreateComponent

  • 각 데코레이터 안에는 Component 객체가 들어 있다.
  • 데코레이터에는 구성요소의 레퍼런스를 포함한 인스턴스 변수가 있다.

ConcreateDecorator

  • 감싸고 있는 Component 객체용 인스턴스 변수가 있다.

 

예제 구조

 

 

코드

Beverage

package headfirst.patterns.decorator.coffee;

import lombok.Getter;

@Getter
public abstract class Beverage {
    String description = "";
    public enum Size{TALL, GRANDE, VENTI};
    Size size = Size.TALL;

    public void setSize(Size size) {
        this.size = size;
    }


    public abstract double cost();
}

 

Espresso

  • Beverage 를 상속받아서 만든다.
  • 그렇게 되면 다형성을 가지게 된다.
  • 상속을 사용한 이유는 CondimentDecorator 에서 Beverage 를 선언하여 어떤종류의 커피도 받을수 있도록 하기 위함이다.
package headfirst.patterns.decorator.coffee;

public class Espresso extends Beverage {
    public Espresso() {
        description = "espresso";
    }

    public double cost() {
        return 1.99;
    }
}

 

CondimentDecorator

  • Beverage 를 상속받은 이유는 코스트를 내부에서 쉽게 계산하기 위함이다.
  • 그래야 모든 값과 비용을 계산 할 수 있다.
  • Espresso 의 가격도 알아야 하고 토핑의 가격도 알아야 하기 때문이다.
package headfirst.patterns.decorator;

import headfirst.patterns.decorator.coffee.Beverage;

public abstract class CondimentDecorator extends Beverage {
    Beverage beverage;
    public abstract String getDescription();
    public Size getSize() {
        return beverage.getSize();
    }
}

 

Mocha

  • 여기서부터 데코레이터를 위한 상속을 받았고 
  • 생성자에서 Beverage 를 주입받는다. 모카도 결국 Beverage를 상속받았기 때문에
    다른 토핑도 들어올수 있게 된다.
public class Mocha extends CondimentDecorator{
    public  Mocha(Beverage beverage) {
        this.beverage = beverage;
    }

    @Override
    public double cost() {
        return beverage.cost() + 0.20;
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", mocha";
    }
}

 

 

테스트 코드

        Beverage beverage = new Espresso();
        System.out.println(beverage.getDescription());

        beverage = new Mocha(beverage);
        beverage = new Mocha(beverage);
        Assertions.assertEquals(beverage.cost(),2.49);

 

 

 

전체코드

https://github.com/rnrl1215/design-pattern/tree/main/src/main/java/headfirst/patterns/decorator

 

GitHub - rnrl1215/design-pattern

Contribute to rnrl1215/design-pattern development by creating an account on GitHub.

github.com

 

 

참고:

http://www.yes24.com/Product/Goods/108192370?pid=123487&cosemkid=go16481149710577107&gclid=CjwKCAiAqt-dBhBcEiwATw-ggFw6kBwGL_yr97ai8Ultf27DiTnj-9N17tiScmO0opapi7d6wPROqRoCrtIQAvD_BwE 

 

헤드 퍼스트 디자인 패턴 - YES24

유지관리가 편리한 객체지향 소프트웨어 만들기!“『헤드 퍼스트 디자인 패턴(개정판)』 한 권이면 충분하다.이유 1. 흥미로운 이야기와 재치 넘치는 구성이 담긴 〈헤드 퍼스트〉 시리즈! 하나

www.yes24.com

 

728x90
반응형

'Design pattern > GoF(HeadFirst)' 카테고리의 다른 글

[HeadFirst] 커맨드 패턴  (0) 2023.02.10
[HeadFirst] 옵저버 패턴  (0) 2022.12.03

댓글