- 클래스에게 동적인 기능이나 임무를 추가하는 패턴
- 기존 객체를 유연성 있게 확장할 때
- 객체의 추가적인 요건을 동적으로 추가
- 서브클래스 통해 기능을 유연하게 확장할 수 있는 방법을 제공
- 서브 클래스가 많아지게 되면 관리하기에 복잡할 수 있음 (예] 자바의 I/O 클래스 구성체계)
- 상속을 통해 확장할 수 있지만, 디자인 유연성 면에서 좋지 않음
Coffee 클래스
class Coffee { public: virtual int GetCost() = 0; virtual string GetIngredients() = 0; };
DefaultCoffee 클래스
class DefaultCoffee : public Coffee { public: virtual int GetCost() { return 500; }; virtual string GetIngredients() { return "Coffee"; }; };
CoffeeDecorator 클래스
class CoffeeDecorator : public Coffee { public: CoffeeDecorator(Coffee* pCoffee) { m_pCoffee = pCoffee; }; protected: Coffee* m_pCoffee; };
Milk, WhippingCream 클래스
class Milk :public CoffeeDecorator { public: Milk(Coffee* pCoffee) : CoffeeDecorator(pCoffee) {}; virtual int GetCost() { return m_pCoffee->GetCost() + 200; }; virtual string GetIngredients() { return m_pCoffee->GetIngredients() + ", Milk"; }; }; class WhippingCream :public CoffeeDecorator { public: WhippingCream(Coffee* pCoffee) : CoffeeDecorator(pCoffee) {}; virtual int GetCost() { return m_pCoffee->GetCost() + 100; }; virtual string GetIngredients() { return m_pCoffee->GetIngredients() + ", Whipping Cream"; }; };
실행부분
void main() { auto_ptr<Coffee> pCoffee(new DefaultCoffee()); cout << "-- DefaultCoffee -- " << endl; cout << "Cost: " << pCoffee->GetCost() << endl; cout << "Ingredients: " << pCoffee->GetIngredients().c_str() << endl; auto_ptr<Coffee> pCoffeeDec1(new Milk(pCoffee.get())); cout << "-- DefaultCoffee + Milk -- " << endl; cout << "Cost: " << pCoffeeDec1->GetCost() << endl; cout << "Ingredients: " << pCoffeeDec1->GetIngredients().c_str() << endl; auto_ptr<Coffee> pCoffeeDec2(new WhippingCream(pCoffeeDec1.get())); cout << "-- DefaultCoffee + Milk + WhippingCream -- " << endl; cout << "Cost: " << pCoffeeDec2->GetCost() << endl; cout << "Ingredients: " << pCoffeeDec2->GetIngredients().c_str() << endl; }
UML - class 다이어그램
- GoF의 디자인 패턴(개정판) 재사용성을 지닌 객체지향 소프트웨어의 핵심요소
- http://h_proms.blog.me/220383634118
댓글 없음:
댓글 쓰기
참고: 블로그의 회원만 댓글을 작성할 수 있습니다.