Java 디자인 패턴-11.Decorator
(Java 디자인 패턴 스터디 모집 중 : https://github.com/bluedskim/javaDesignPatterns)
Decorator 패턴
(출처:https://stefanhenneken.net/2019/02/16/iec-61131-3-the-decorator-pattern)
해결하려는 문제
특징/용도
- 런타임에 객체에 동적으로 기능을 추가하기 위한 structural 패턴
- 래퍼wrapper 클래스로 구현.
- chain of responsibility pattern과 유사함
- 생성자 혹은 다른 메소드에서 해당 클래스 자체를 인수로 받는 경우 데코레이터라 볼 수 있다(https://refactoring.guru/design-patterns/decorator/java/example)
고려사항
클래스 다이어그램
소스
- 꾸며질decorated 객체
- BeverageBase.java : 부모 abstract 객체
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
package net.dskim.desingpattern.decorator;
abstract class BeverageBase {
protected String description = "";
public String getDescription() {
return description;
}
/**
* 가격을 계산하는 로직은 하위 객체가 구현해야 한다.
* @return
*/
public abstract double getCost();
}
|
- BlackTea.java
1
2
3
4
5
6
7
8
9
10
11
12
13
|
package net.dskim.desingpattern.decorator;
class BlackTea extends BeverageBase {
public BlackTea() {
description = "Black tea from teabag";
}
@Override
public double getCost() {
return 5;
}
}
|
- Espresso.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
package net.dskim.desingpattern.decorator;
abstract class BeverageBase {
protected String description = "";
public String getDescription() {
return description;
}
/**
* 가격을 계산하는 로직은 하위 객체가 구현해야 한다.
* @return
*/
public abstract double getCost();
}
|
- GreenTea.java
1
2
3
4
5
6
7
8
9
10
11
12
13
|
package net.dskim.desingpattern.decorator;
class GreenTea extends BeverageBase {
public GreenTea() {
description = "Green leaf tea";
}
@Override
public double getCost() {
return 8;
}
}
|
- 꾸미는decorator 객체
- CondimentsDecoratorBase.java : 부모 abstract 객체
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
package net.dskim.desingpattern.decorator;
/**
* 데코레이터 객체
*/
abstract class CondimentsDecoratorBase extends BeverageBase {
BeverageBase beverage;
/**
* 생성자에서 BeverageBase의 참조를 받아서 멤버변수에 할당
* @param beverage
*/
protected CondimentsDecoratorBase(BeverageBase beverage) {
this.beverage = beverage;
}
}
|
- CholateCondiment.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
package net.dskim.desingpattern.decorator;
class ChocolateCondiment extends CondimentsDecoratorBase {
/**
* 생성자에서 해당 클래스 자체를 인수로 받는다
*/
public ChocolateCondiment(BeverageBase beverage) {
super(beverage);
description = beverage.getDescription() + " + Chocolate";
}
@Override
public double getCost() {
return beverage.getCost() + 4;
}
}
|
- MilkCondiment.java
1
2
3
4
5
6
7
8
9
10
11
12
13
|
package net.dskim.desingpattern.decorator;
class MilkCondiment extends CondimentsDecoratorBase {
public MilkCondiment(BeverageBase beverage) {
super(beverage);
description = this.beverage.getDescription() + " + Milk";
}
@Override
public double getCost() {
return beverage.getCost() + 3;
}
}
|
- SugarCondiment.java
1
2
3
4
5
6
7
8
9
10
11
12
13
|
package net.dskim.desingpattern.decorator;
class SugarCondiment extends CondimentsDecoratorBase {
public SugarCondiment(BeverageBase beverage) {
super(beverage);
description = beverage.getDescription() + " + Sugar";
}
@Override
public double getCost() {
return beverage.getCost() + 1;
}
}
|
참고