[3장] Decorator Pattern

ss0510s·2022년 7월 10일
0

Decorator Pattern

객체에 추가요소를 동적으로 더할 수 있다. 서브 클래스를 만들 때마다 훨씬 유연하게 확장이 가능하다.

OO 원칙

  • 클래스는 확장에는 열려있어야 하지만, 변경에는 닫혀있어야 한다.

커피 메뉴

  • 슈퍼클래스 Beverage에 여러 개의 커피 메뉴 클래스를 상속으로 추가할 경우, 많은 수의 상속 관계가 발생하는 문제점이 있다.
  • 따라서 음료에 여러 첨가물들을 장식(데코레이트)하는 방법으로 구현한다.
  • 변하는 부분: 음료 이름, 가격
  • Decorator은 Component를 꾸밀 수도, 아닐 수도 있다.

Abstract Class

  • 추상 클래스
public abstract class Beverage {

	// 음료 이름
	String description = "Unknown Beverage";
	public String getDescription() {
		return description;
	}
	// cost 추상 메서드
	public abstract double cost();
}

Concrete Class

  • Beverage를 상속받는 구상 클래스를 구현한다.
  • 원본 객체로 데코레이팅이 가능하다.
public class Espresso extends Beverage {
	public Espresso() {
    	description = "Espresso";
    }
    public double cost(){
    	return 1.99;
    }
}

...

Decorator Class

public abstract class CondimentDecorator {
	Beverage beverage; // 데코레이터가 감쌀 음료를 저장
    public abstract String getDescription();
}

Decorator Concrete Class

  • 데코레이터 클래스를 상속받는 구상 클래스이다.
  • 생성자에서 기존 객체를 받고, 메서드에서는 받은 객체에 추가적으로 요소를 더한다.
public class Mocha extends CondimentDecorator {
	public Mocha(Beverage beverage) {
    	this.beverage = beverage; // Beverage 객체 참조
    }
    public String getDescription() {
    	return beverage.getDescription() + ", Mocha";
    }
    public double cost() {
    	return beverage.cost() + .20;
    }
}

Test.java

  • 동적으로 요소를 더할 수 있다.
public class StarbuzzCoffee {
 
	public static void main(String args[]) {
		Beverage beverage = new Espresso(); // 객체 생성

		System.out.println(beverage.getDescription() 
				+ " $" + String.format("%.2f", beverage.cost()));

		// 데코레이터 패턴 - 객체를 계속 whip
		beverage = new Mocha(beverage);
		beverage = new Mocha(beverage);
		beverage = new Whip(beverage);
		System.out.println(beverage.getDescription() 
				+ " $" + String.format("%.2f", beverage.cost()));
	}
}

장단점

장점

  • 서브클래스를 사용하는 것 보다 유연하게 확장이 가능하다. -> OCP 원칙 만족
  • 여러 동작들을 결합할 수 있다.

단점

  • Wrapper 스택에서 특정 Wrapper을 제거하기 어렵다.
  • 데코레이팅 스택 순서가 정해지기 때문에 순서에 의존하지 않고 데코레이팅 하기 어렵다.
profile
개발자가 되기 위해 성장하는 중입니다.

0개의 댓글