상속은 기능을 확장하는 방법을 제공한다. 하지만 다양한 조합의 기능 확장이 요구될 때 클래스가 불필요하게 증가하는 문제가 발생된다.
-> 이러한 경우에 사용할 수 있는 패턴이 데코레이터 패턴이다.
: 상속이 아닌 위임을 하는 방식으로 기능을 확장해간다.
: 동적(실시간으로 기능 변경), 책임 추가!
기능 확장을 위해 impl class를 상속받지 않고 decorator라 불리는 별도의 추상 클래스를 만들었다.
컴포넌트를 구현하는 게 컨크리트컴포넌트와 데코레이터이다.
커피로 예를 들어보자,
에스프레소: 커피의 기본
아메리카노 : 에스프레소 + 물
카페라떼 : 에스프레소 + 스팀 밀크
헤이즐넛 : 아메리카노 + 헤이즐넛 시럽
카페모카 : 카페라떼 + 초콜릿
카라멜 마끼아또: 카페라떼 + 캬라멜 시럽
// Component
public class IBeberage{
public int getTotalPrice();
}
// ContreteComponent
public class Base() implements IBeverage{
@Override
public int getTotalPrice() {
return 0;
}
}
// Decorator
abstract public class AbstAdding implements IBeverage {
priate IBeverage base;
public AbstAdding(IBeverage base) {
super();
this.base = base;
}
@Override
public int getTotalPrice(){
return base.getTotalPrice();
}
protected IBeverage getBase(){
return base;
}
// Concrete Decorator
public class Milk extends AbstAdding{
public Milk(IBeverage material){
super(meterial);
}
@Ovveride
public int getTotalPrice() {
return super.getTotalPrice() + 50;
}
}
public class Espresso extends AbstAdding{
public Espresso(IBeverage material){
super(meterial);
}
@Ovveride
public int getTotalPrice() {
return super.getTotalPrice() + 150;
}
}
//main
void main(){
IBeverage beverage = new Base();
beverage.getTotalPrice();
beverage = new Espresso(beverage)'
}