2016년 1월 1일 금요일

Decorator Pattern (작성자 패턴)

의도
  • 클래스에게 동적인 기능이나 임무를 추가하는 패턴
이럴 때 사용하자.
  • 기존 객체를 유연성 있게 확장할 때 
장점은?
  • 객체의 추가적인 요건을 동적으로 추가
  • 서브클래스 통해 기능을 유연하게 확장할 수 있는 방법을 제공
단점은?
  • 서브 클래스가 많아지게 되면 관리하기에 복잡할 수 있음 (예] 자바의 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

댓글 없음:

댓글 쓰기

참고: 블로그의 회원만 댓글을 작성할 수 있습니다.