Decorator Pattern (데코레이터 패턴)
데코레이터 패턴
- 데코레이터는 서브 클래스를 만드는 것을 통해서 기능을 유현하게 확장할 수 있는 방법을 제공한다.
- 한 객체를 여러 개의 테코레이터로 감쌀수 있다.
- 기존 코들르 수정하지 않고도 기능을 확장할 수 있다.
단점
- 데코레이터 패턴을 이용해 디자인을 하다 보면 답다한 클래스가 많아질 수 있음
- 겹겹이 애워싼 객체의 정체를 알기가 힘들다
- 상속을 통해 확장할 수도 있지만, 디자인 유연성 면에서는 별로 좋지 않다.
그럼 이제부터 데이레이터 패턴 사용 하지 않은 예를 들면 !!
카페에서 음료를 주문할때 음료하나에 시럽,우유,휘핑 등을 추가하는 경우가 있다.
이 행동을 구현하면
- 음료를 나타내는 추상 메소드 Beverage 는 카페에서 판매되는 모든 음료는 이 클래스의 서브 클래스가 된다. 즉 Beverage 가 부모클래스 , 슈퍼클래스 이다.
- beverage 라는 음료 클래스에 우유,두유,모카,휘핑 크림을 나타내는 인스턴스 변수를 추가한다.
- 첨가물에 첨부 여부와 첨가물을 설정한다
- cost() 에서 추가된 첨가물의 가격을 계산한다. 서브클래스에서 cost()메소드를 재구현한다.
자 근데 이런식으로 하면 문제점이 무엇인가 ?
첨가물 가격이 바뀔때 마다 기존 코드를 수정해야된다.
첨가물의 종류가 많아지면 새로운 메소드를 추가해야한다.
새로운 음료가 출시될 수도 있다. 그 중에는 첨가물이 들어가면 안되는 음료도 있다. !! (필요없는 첨가물 메소드 상속 받게됨)
손님이 모카를 두번 추가하면 어떻게 할것인가 ????
부모클래스와 자식클래스
- 자식클래스를 만드는 방식으로 행동을 상속 받으면 그 행동은 컴파일시! 완전히 결정되고 모든 서브 클래스에서 똑같은 행동을 상속 받아야한다.
- 하지만 구성을 통해 객체의 행동을 확장하면 실행 중에 동적으로 행동을 설정할 수 있다.
Decorator pattern 적용
- Beverage 는 가장 기본이 되는 Component 클래스이다.
- 음료 종류마다 Beverage에 대한 구상 클래스를 하나씩 만든다. (DripCoffee,DripCoffee)
- 각각의 첨가물을 나타내는 데코레이터를 추가(Mocha, Milk )하고 cost(), getDescription() 를 구현해야한다.
- 각 데코레이터 안에는 Beverage 클래스가 들어있다.
- 데코레이터에는 구성요소에 대한 레퍼런스가 들어있는 인스턴스 변수가 있다!!! (private Beverage beverage)
Beverage.java
DripCoffee.java
Espresso.java
CondimentDecorator.java
Milk.java
Mocha.java
StarbuckCafe.java
결과
에스프레소, 우유$2.29
제목없음$3.21