Computer Theory/Design partterns

데코레이터 패턴

jheaon 2023. 9. 18. 23:26

 

데코레이터 패턴 (Decorator pattern)

객체에 추가적인 요건을 동적으로 첨가하는 패턴이다. 데코레이터는 서브 클래스를 만드는 것을 통해서 기능을 유연하게 확장 할 수 있는 방법을 제공하는 패턴이다. 

 

 

상황

카페에서 커피 사업을 시작하여 주문 시스템을 도입했다고 가정한다. 

 

 

카페에서 마실 음료에서는 스팀우유, 모카, 두유, 등등 기타 추가 첨가물이 필요할 수 있다. 하지만 각각의 첨가물을 추가 하게 된다면 커피의 가격이 올라가고 주문 시스템에서도 해당 첨가물에 대한 부분을 모두 고려하여야 한다. 

 

이런 부분을 고려하여, 첨가물을 옵션 여부로 나타내는 인스턴스 변수로 넣어서 코드를 작성하게 된다면 아래와 같이 작성 할 수 있다. 

 

 

이를 통해 슈퍼클래스에서 구현한 cost을 호출하여 추가가격을 구한다면 아래와 같이 코드를 작성 할 수 있다. 

public class Beverage {

	// 변수 메소드

	public int cost() {

		int totCost = 0;

		if (hasMilk())
			totCost += milkCost;

		if (hasSoy())
			totCost += soyCost;

		if (hasMocah())
			totCost += mocahCost;

		if (hasWhip())
			totCost += whipCost;

		return totCost;

	}

}

public class DarkRoast extends Beverage {

	@Override

	public int cost() {

		return 4500 + super.cost();

	}

}

하지만 해당 코드는 첨가물의 가격이 바뀔 때마다 기존 코드의 수정을 하여야 하며, 첨가물의 종류가 증가함에 따라 새로운 메소드를 추가해주어야 하며 슈퍼클래스에 있는 cost메소드를 계속 고쳐주어야 한다.

 

이런 문제를 해결하기 위해 나온 패턴이 데코레이션 패턴이다. 

 

데코레이터 패턴은 자신이 장식하는 객체에게 행동을 위임하거나 추가 작업을 수행할 수 있게 하며, 데코레이터의 슈퍼클래스는 자신이 장식하는 객체의 슈퍼클래스와 같기 때문에 원래 객체가 들어갈 자리에 데코레이터 객체를 넣어도 된다. 또한 객체는 언제든지 감쌀 수 있으므로 동적으로 적용이 가능하다는 것이 특징이다. 

 

따라서 해당 패턴을 적용하여 주문 시스템을 설계하게 된다면 아래와 같이 설계가 가능하다. 

 

이를 코드로 구현한다면 다음과 같이 구현이 가능하다. 

 

 

Beverage 구현

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

	public String getDescription() {
		return description;
	}

	public abstract double cost();
}

 

 

 

CondimentDecorator 구현

public abstract class CondimentDecorator extends Beverage { 
	Beverage beverage;

	public abstract String getDescription();
}

 

 

 

Espresso 구현

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

}

 

 

Mocha 구현

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 beverage2 = new Espresso();
		beverage = new Mocha(beverage); // Mocha로 감싼다
		beverage = new Mocha(beverage); // Mocha로 감싼다
		beverage = new Whip(beverage); // Whip으로 감싼다

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

 


참고 : 

https://swk3169.tistory.com/226

 

헤드퍼스트 디자인 패턴: 데코레이터 패턴 (Decorator Pattern)

데코레이터 패턴 (Decorator Pattern) 객체에 추가적인 요건을 동적으로 첨가한다. 데코레이터는 서브클래스를 만드는 것을 통해서 기능을 유연하게 확장할 수 있는 방법을 제공한다. 데코레이터 패

swk3169.tistory.com

https://greensky0026.tistory.com/265

 

헤드퍼스트 디자인 패턴 03.데코레이터(Decorator) 패턴

* 본 포스팅은 한빛미디어의 헤드퍼스트 디자인 패턴을 공부한 내용을 정리한 글입니다. 저의 부족한 생각과 주관으로 틀린 내용이 있을 수 있으니, 자세한 내용이 궁금하시다면 해당 책을 읽어

greensky0026.tistory.com

 

'Computer Theory > Design partterns' 카테고리의 다른 글

디자인 패턴과 SOLID 원칙  (0) 2024.05.22
팩토리 패턴  (0) 2023.09.20
옵저버 패턴  (0) 2023.09.04
전략 패턴  (0) 2023.08.30

'Computer Theory/Design partterns'의 다른글

  • 현재글 데코레이터 패턴

관련글