Design Pattern

[Design Pttern] 데코레이터 패턴

JiWonSon 2023. 2. 5. 09:41

1. 데코레이터 패턴?

- 데코레이터 패턴으로 객체에 추가 요소를 동적으로 더할 수 있는 패턴이다.

- 데코레이터를 사용하면 서브클래스를 만들 때보다 훨 씬 유연하게 기능을 확장할 수 있다.

 

[역할]

Component : 실질적인 인스턴스를 컨트롤하는 역할

ConcreteComponent : Component의 실질적인 인스턴스의 부분으로 책임의 주체의 역할

Decorator : Component와 ConcreteDecorator를 동일시 하도록 해주는 역할

ConcreteDecoreator : 실질적인 장식 인스턴스 및 정의이며 추가된 책임의 주체

 

2. 데코레이터 패턴의 장단점

장점

1. 기존 코드를 수정하지 않고도 데코레이터 패턴을 통해 행동을 확장시킬 수 있다.

2. 구성과 위임을 통해서 실행중에 새로운 행동을 추가할 수 있다.

 

단점

1. 의미없는 객체들이 너무 많이 추가될 수 있다.

2. 데코레이터를 너무 많이 사용하면 코드가 필요 이상으로 복잡해질 수 있다.

 

3. 데코레이터를 이용한 주문시스템 클래스 구성도

- 제일 상단의 Beverage는 구성요소를 나타내는 Component 추상 클래스이다.

- HoustBlend, DarkRoast, Decaf, Espresso는 커피 종류마다의 구성요소를 나타내는 구상 클래스이다.

- Milk, Mocha, Soy, Whip은 각각의 첨가물을 나타내는 데코레이터이다.

 

 

4. 데코레이터를 사용해 주문시스템 구현

 

[추상 구성요소] Beverage

public abstract class Beverage {
	String description = "제목 없음";

	public String getDescription() {
		return description;
	}

	public abstract double cost();
}
//Beverage 클래스를 확장
public abstract class CondimentDecorator extends Beverage { 
	Beverage beverage;

	public abstract String getDescription();
}

- Beverage 객체가 들어갈 자리에 들어갈 수 있어야 한다. 따라서 Beverage 클래스를 확장한다.

- 모든 첨가물 데코레이터에서 getDescription() 메소드를 새로 구현하기 위해서 추상 메소드로 선언한다.

 

[구상 구성요소] Espresso, Decaf

public class Espresso extends Beverage {
	
	public Espresso() {
		description = "에스프레소";
	}
	
	public double cost() {
		return 1.99;
	}

}
public class Decaf extends Beverage {
	
	public Espresso() {
		description = "디카페인 커피";
	}
	
	public double cost() {
		return 1.05;
	}

}

[구상 데코레이터]

public class Mocha extends CondimentDecorator {
	
	// 감싸고자 하는 객체를 받음
	public Mocha(Beverage beverage) {
		// 감싸고자 하는 음료를 저장
		this.beverage = beverage; 
	}

	public String getDescription() {
		return beverage.getDescription() + ", 모카";
	}

	public double cost() {
		return beverage.cost() + .20;
	}

}

- 데코레이터는 감싸고자하는 음료를 저장하기 위한 인스턴스가 필요하다.

 

[주문 테스트 코드]

public class StarbuzzCoffee {
	
	public static void main(String args[]) {
		Beverage beverage = new Espresso();
		beverage = new Mocha(beverage); // Mocha로 감싼다
		beverage = new Mocha(beverage); // Mocha로 감싼다
		
                Beverage beverage2 = new Decaf();
                beverage2 = new Whip(beverage2); // Whip으로 감싼다

		System.out.println(beverage.getDescription() + " $" + beverage.cost());
		// 에스프레소 커피, 모카, 모카 $1.99
		System.out.println(beverage2.getDescription() + " $" + beverage.cost());
		// 디카페인 커피, 휘핑크림 $2.49
	}
}

'Design Pattern' 카테고리의 다른 글

[Design Pattern] 템플릿 메소드 패턴  (0) 2023.03.05
[Design Pattern] MVC패턴  (0) 2023.01.09
[Design Patter] 상태패턴  (0) 2023.01.07
[Design Pattern] 싱글톤 패턴  (0) 2022.12.17