////
Search

3장 - 데코레이터 패턴

Created
2022/09/03 11:29
Tags
디자인패턴

데코레이터 패턴이란?

데코레이터 패턴 클래스 다이어그램
데코레이터 패턴은 객체에 추가요소를 동적으로 더할 수 있다. 데코레이터를 사용하면 서브클레스를 만들 때보다 훨씬 유연하게 기능을 확장할 수 있습니다.
데코레이터 패턴은 Component클래스를 상속받는다.
데코레이터 형식이 그 데코레이터로 감싸는 객체의 형식과 같다.
상속으로 행동을 물려받는게 아니기 때문에 상속을 받아도 문제가 되지 않는다.
한 객체를 여러 개의 데코레이터로 감쌀 수 있다.
데코레이터는 자신이 장식하고 있는 객체에게 어떤 행동을 위임하는 일 말고도 추가작업을 수행할 수 있습니다.
객체는 언제든지 감쌀 수 있으므로 실행중에 필요한 데코레이터를 마음대로 적용할 수 있습니다.

요구사항

스타버즈의 음료 주문 시스템을 구축한다.
커피를 기반으로한 여러가지 음료들을 판매한다.
커피에 우유를 추가하면 라떼, 초콜릿을 추가하면 카페모카 등 다양한 형태로 변형될 수 있다.

해결 방법 1 : 상속을 통한 구현 (1)

단점

너무 많은 클래스가 만들어졌음
행동을 상속 받았기 때문에 확장에 어려움이 있음

해결 방법 2 : 상속을 통한 구현 (2)

슈퍼클래스에서 첨가물을 추가해서 각 클래스가 관리하는 방법

단점

클래스의 수는 적어졌지만, 슈퍼클래스의 의존성이 더욱 높아졌음
첨가물의 가격이 바뀔때마다 코드를 수정해야 함
첨가물의 종류가 많아지면 슈퍼클래스에서 메소드를 추가해줘야 함
새로운 음료가 첨가물이 포함되면 안되는 음료일 수 있음

해결 방법 3 : 데코리이터 패턴 적용

데코레이터 패턴을 적용한 모습
// 음료객체 public abstract class Beverage { String description = "제목없음"; public String getDescription() { return description; } public abstract double cose(); } // Beverage 데코레이터 public abstract class CondimentDecorator extends Beverage { Beverage beverage; // 데코레이터가 감쌀 음료 객체 public abstract String getDescription(); // 객체에 값을 더해 출력할 설명 추상 메소드 } public class Espresso extends Beverage { public Espresso() { description = "에스프레소"; } public double cost() { return 1.99; } } 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 StarbuzzCoffe { public static void main(String args[]) { // 베이스가 될 음료 객체 생성 Beverage beverage = new Espresso(); System.out.println(beverage.getDescription() + " $" + beverage.cost()); // 모카 데코레이터로 객체를 장식! beverage = new Mocha(beverage); System.out.println(beverage.getDescription() + " $" + beverage.cost()); } }
Java
복사
데코레이터가 적용된 스타버즈 시스템의 코드

장점

OCP(Open-Closed Principle, 개방폐쇄 원칙)를 지키며 기능을 확장할 수 있다.
추후 음료의 첨가물이 추가되거나, 음료가 추가되더라도 추가적인 수정을 요하지 않는다.

단점

데코레이터 패턴을 사용하면 관리해야 할 객체가 늘어나니 코딩 실수가 발생할 가능성이 높아진다.
실제로는 팩토리나 빌더를 통해서 극복할 수 있다.