Header

  1. View current page

    jinsu0000님의 IT 노트

Profile_image?t=1298394238&type=big
교만하지 말지어다.
37

070626_D.P

 

팩토리와 컴포짓 패턴(탐색기) 데코레이션 패턴

# 데코레이터 패턴    -크림과 우유 주문-

  •  Beverage(음료) 클래스와 그속의 descriotion 그리고 그것을 가져오는 getDescription()와 cost()를 만든다.
  • 밑에 4개의 상속받는 클래스들 HouseBlend / DarkRoast / Decaf / Espresso 클래스를 만들고 각각의 cost()를 재정의 한다.
  • 하지만 얹는 토핑과 크림, 모카등의 추가로 가격이 바뀐다.
  • 때문에 다른 방법을 찾는다. -  Beverage 클래스의descrption속에 재료를 넣어버리면 되는것. hasMilk() , hasWhip() 등의 재료 get함수와 set함수도 만들어 부모 클래스에 넣어준다.
  • 여기까지의 문제점. 
    1.  첨가물의 가격이 바뀔 때 마다 기존 코드를 수정해야 한다.(OpenClosePre.. 원리를 위배함)
    2.  첨가물의 종류가 추가 되면 새로운 함수를 추가해야 하고, cost() 함수도 추가해야 한다.
    3. 첨가물이 들어가면 안되는 Tea 서브 클래스에서도 has whip과 같은 함수를 상속 받게 된다.
    4.  손님이 더블 모카를 주문하면 어떻게 해야 하나?
  •  =>해결) 데코레이터 패턴을 사용.
  • 컴퍼넌트 클래스에 상속받는 콘크리트(구현) 컴퍼넌트와 데코레이터 클래스를 만들고, 데코레이터 클래스에 상속받는 콘크리트 데코레이터 A와  콘크리트 데코레이터 B 클래스를 만든다.
  • 데코레이터 패턴에서는 객체에 추가적인 요건을 동적으로 첨가한다. 데코레에터는 서브 클래스를 만드는 것을 통해서 기능을 유연하게 확장할 수 있는 방법을 제공한다.
  • 각 데코레이터 패턴안에는 component 객체가 들어있다. 즉, 데코레이터에는 구성요소에 대한 레퍼런스가 들어 있는 인스턴스 변수이다.
  •  Beverage 객체아래 concreat 객체들(Espressom Decaf...등등)과 CondimentDecorator(getDescrotion()포함)객체를 만들고, Beverage를 감싸안는 포인터를 가지는  콘크리트 condimentDecorator 자식 함수들(milk,soy,whip...등등)을 만든다.
  • CondimentDecorator객체는 디폴트로 함수 선언이 가능하다. 자식에서 재정의 되었기 때문이다.
  • 변화에는 닫혀있고 확장에는 열려있는 코드이다.

 

#팩토리 패턴   -피자 주문-

  • 피자를 주문하면 추상의 피자를 만들고(new) 피자를 준비해서, 만들고, 자르고, 박스에 넣는 함수를 가진다. 다형성을 이용해서 피자의 종류를 고르게 할 수 도 있다.
  • 하지만..... 유연성을 감안하여 추상클래스로 만들면 좋지만 추상클래스는 인스턴스로 만들 수 없다. 실제 인스턴스 화 시킬땐 분기를 이용, 다형성을 이용하게 한다.
  • 또한 변화하는 것은 밖으로 빼서 캡슐화 하는 것이 유리하다.  팩토리라는 클래스를 만들어 클래스를 생성하는 클래스로 만드는 것이다.
  •  간단한 팩토리.
  • 피자 추상 클래스피자를 만들고 피자의 상속을 받는 여러가지 피자를 만든다.
  • 팩토리 메쏘드!  - 분점을 자식으로 상속해서 쓰자.
  • 프레임 워크. 부모가 실행순서를 정의해놓고 자식이 재정의해서 쓰되 순서를 바꿔쓰지 못하게 하는 것.
  • 객체의 생성을 자식 팩토리에게 위임한다. 팩토리 메쏘드.

[과제] _ (금요일까지) pizzaaf를 주석 잔뜩 달아서 그림도 그려보고 C++로 만들어서 돌아가게 제출해라   [Homework]_pizzaaf_0706신진수.cpp

 

 

  1.  #include <iostream>
    #include <string>
    using namespace std;
  2. struct Beverage
    {
     string description;
     Beverage( string desc="Unknown Beverage" ) : description(desc) {}
     
     virtual string getDescription()
     {
      return description;
     }
     
     virtual double cost()=0;
    };
  3. class Espresso : public Beverage
    {
    public:
     Espresso()
     {
      description = "Espresso";
     }
     
     double cost()
     {
      return 1.99;
     }
    };

  4. class DarkRoast : public Beverage {
    public:
     DarkRoast()
     {
      description = "Dark Roast Coffee";
     }
     
     double cost()
     {
      return .99;
     }
    };
  5. class Decaf :public Beverage
    {
    public:
     Decaf()
     {
      description = "Decaf Coffee";
     }
     
     double cost()
     {
      return 1.05;
     }
    };
  6. class HouseBlend : public Beverage
    {
    public:
     HouseBlend()
     {
      description = "House Blend Coffee";
     }
     
     double cost()
     {
      return .89;
     }
    };
  7. class CondimentDecorator : public Beverage
    {
    public:
     virtual string getDescription()=0;
    };
  8. class Milk : public CondimentDecorator
    {
     Beverage *beverage;
  9. public:
     Milk(Beverage *beverage)
     {
      this->beverage = beverage;
     }
  10.  string getDescription()
     {
      return beverage->getDescription() + ", Milk";
     }
  11.  double cost()
     {
      return .10 + beverage->cost();
     }
    };
  12. class Mocha : public CondimentDecorator
    {
     Beverage *beverage;
     
    public:
     Mocha(Beverage *beverage)
     {
      this->beverage = beverage;
     }
     
     string getDescription()
     {
      return beverage->getDescription() + ", Mocha";
     }
     
     double cost()
     {
      return .20 + beverage->cost();
     }
    };
  13. class Soy : public CondimentDecorator
    {
     Beverage *beverage;
  14. public:
     Soy(Beverage *beverage)
     {
      this->beverage = beverage;
     }
  15.  string getDescription()
     {
      return beverage->getDescription() + ", Soy";
     }
  16.  double cost()
     {
      return .15 + beverage->cost();
     }
    };
  17. class Whip : public CondimentDecorator {
     Beverage *beverage;
     
    public:
     Whip(Beverage *beverage)
     {
      this->beverage = beverage;
     }
     
     string getDescription()
     {
      return beverage->getDescription() + ", Whip";
     }
     
     double cost()
     {
      return .10 + beverage->cost();
     }
    };
  18. class Honey : public CondimentDecorator {
     Beverage *beverage;
     
    public:
     Honey(Beverage *beverage)
     {
      this->beverage = beverage;
     }
     
     string getDescription()
     {
      return beverage->getDescription() + ", Honey";
     }
     
     double cost()
     {
      return .50 + beverage->cost();
     }
    };
  19. int main()
    {
     Beverage *beverage = new Espresso;
     cout << beverage->getDescription() + " $" << beverage->cost() << endl;
  20.  Beverage *beverage2 = new DarkRoast;
     beverage2 = new Mocha(beverage2);
     beverage2 = new Mocha(beverage2);
     beverage2 = new Whip(beverage2);
     beverage2 = new Honey(beverage2);
     cout << beverage2->getDescription() + " $" << beverage2->cost() << endl;
  21.  Beverage *beverage3 = new HouseBlend;
     beverage3 = new Soy(beverage3);
     beverage3 = new Mocha(beverage3);
     beverage3 = new Whip(beverage3);
     beverage3 = new Honey(beverage3);
     cout << beverage3->getDescription() + " $" << beverage3->cost() << endl;
     return 0;
    }

 

  1.  /*
    Pizza *orderPizza()
    {
     Pizza *pizza = new Pizza();  // 유연성을 감안하여 추상클래스로 만들면 좋지만
                                  // 추상클래스는 인스턴스로 만들수 없다.
  2.  pizza->prepare();
     pizza->bake();
     pizza->cut();
     pizza->box();
  3.  return pizza;
    }
    */

  4. /*
    Pizza *orderPizza(string type)
    {
     Pizza *pizza;
  5.  if( type == "cheeze" )
      pizza = new CheezePizza;
    // else if( type == "greek" )
    //  pizza = new GreekPizza;
     else if( type == "pepperoni" )
      pizza = new PepperoniPizza;
     else if( type == "clam" )
      pizza = new ClamPizza;
     else if( type == "veggie" )
      pizza = new VeggiePizza;
  6.  pizza->prepare();
     pizza->bake();
     pizza->cut();
     pizza->box();
  7.  return pizza;
    }
    */
    #if 0
    #include <iostream>
    #include <string>
    #include <vector>
    using namespace std;
  8. struct Pizza
    {
     string name;
     string dough;
     string sauce;
     vector<string> toppings;
  9.  string getName()
     {
      return name;
     }
  10.  void prepare() {
      cout << name + " Preparing" << endl;
     }
  11.  void bake() {
      cout <<  name + " Baking "  << endl;
     }
  12.  void cut() {
      cout << name + " Cutting "   << endl;
     }
  13.  void box() {
      cout << name + " Boxing "  << endl;
     }
  14.  string toString() {
      string display;
      display += "---- " + name + " ----\n";
      display += dough + "\n";
      display += sauce + "\n";
      for (unsigned int i = 0; i < toppings.size(); i++)
       display += toppings[i] + "\n";
      
      return display;
     }
    };
  15. class CheesePizza : public Pizza {
    public:
     CheesePizza()
     {
      name = "Cheese Pizza";
      dough = "Regular Crust";
      sauce = "Marinara Pizza Sauce";
      toppings.push_back("Fresh Mozzarella");
      toppings.push_back("Parmesan");
     }
    };
  16. class ClamPizza : public Pizza {
    public:
     ClamPizza() {
      name = "Clam Pizza";
      dough = "Thin crust";
      sauce = "White garlic sauce";
      toppings.push_back("Clams");
      toppings.push_back("Grated parmesan cheese");
     }
    };
  17. class VeggiePizza : public Pizza {
    public:
     VeggiePizza() {
      name = "Veggie Pizza";
      dough = "Crust";
      sauce = "Marinara sauce";
      toppings.push_back("Shredded mozzarella");
      toppings.push_back("Grated parmesan");
      toppings.push_back("Diced onion");
      toppings.push_back("Sliced mushrooms");
      toppings.push_back("Sliced red pepper");
      toppings.push_back("Sliced black olives");
     }
    };
  18. class PepperoniPizza : public Pizza {
    public:
     PepperoniPizza() {
      name = "Pepperoni Pizza";
      dough = "Crust";
      sauce = "Marinara sauce";
      toppings.push_back("Sliced Pepperoni");
      toppings.push_back("Sliced Onion");
      toppings.push_back("Grated parmesan cheese");
     }
    };
  19. class SimplePizzaFactory
    {
    public:
     Pizza * createPizza( string type )
     {
      Pizza *pizza = 0;
      if( type == "cheese" )
       pizza = new CheesePizza;
      else if( type == "pepperoni" )
       pizza = new PepperoniPizza;
      else if( type == "clam" )
       pizza = new ClamPizza;
      else if( type == "veggie" )
       pizza = new VeggiePizza;
  20.   return pizza;
     }
    };
  21. class PizzaStore
    {
     SimplePizzaFactory *factory;
  22. public:
     PizzaStore( SimplePizzaFactory *fac ) : factory(fac) {}
  23.  Pizza *orderPizza(string type)
     {
      Pizza *pizza = factory->createPizza( type );
  24.   pizza->prepare();
      pizza->bake();
      pizza->cut();
      pizza->box();
  25.   return pizza;
     }
    };
  26. int main()
    {
     SimplePizzaFactory *factory = new SimplePizzaFactory;
     PizzaStore *store = new PizzaStore(factory);
  27.  Pizza *pizza = store->orderPizza("cheese");
     cout << "We ordered a " + pizza->getName() + "\n";
  28.  pizza = store->orderPizza("veggie");
     cout << "We ordered a " + pizza->getName() + "\n";
  29.  return 0;
    }
    #endif

  30. #if 1
    #include <iostream>
    #include <string>
    #include <vector>
    using namespace std;
  31. struct Pizza
    {
     string name;
     string dough;
     string sauce;
     vector<string> toppings;
  32.  string getName()
     {
      return name;
     }
  33.  void prepare() {
      cout << name + " Preparing" << endl;
     }
  34.  void bake() {
      cout <<  name + " Baking "  << endl;
     }
  35.  void cut() {
      cout << name + " Cutting "   << endl;
     }
  36.  void box() {
      cout << name + " Boxing "  << endl;
     }
  37.  string toString() {
      string display;
      display += "---- " + name + " ----\n";
      display += dough + "\n";
      display += sauce + "\n";
      for (unsigned int i = 0; i < toppings.size(); i++)
       display += toppings[i] + "\n";
      
      return display;
     }
    };
  38. class ChicagoStyleCheesePizza : public Pizza {
  39. public:
     ChicagoStyleCheesePizza() {
      name = "Chicago Style Deep Dish Cheese Pizza";
      dough = "Extra Thick Crust Dough";
      sauce = "Plum Tomatofffffffffffffffffffffffff Sauce";
     
      toppings.push_back("Shredded Mozzarella Cheese");
     }
     
     void cut() {
      cout << "Cutting the pizza into square slices" << endl ;
     }
    };
  40. class NYStyleCheesePizza : public Pizza {
  41. public:
     NYStyleCheesePizza() {
      name = "NY Style Sauce and Cheese Pizza";
      dough = "Thin Crust Dough";
      sauce = "Marinara Sauce";
     
      toppings.push_back("Grated Reggiano Cheese");
     }
    };

  42. class PizzaStore
    {
    public:
     Pizza *orderPizza(string type)
     {
      Pizza *pizza = createPizza( type );
  43.   pizza->prepare();
      pizza->bake();
      pizza->cut();
      pizza->box();
  44.   return pizza;
     }
  45.  virtual Pizza * createPizza(string) = 0;
    };
  46. class NYPizzaStore : public PizzaStore {
     Pizza *createPizza(string item) {
      if (item == "cheese")
       return new NYStyleCheesePizza;
      /*
      else if (item == "veggie")
       return new NYStyleVeggiePizza;
      else if (item == "clam")
       return new NYStyleClamPizza;
      else if (item == "pepperoni")
       return new NYStylePepperoniPizza;
      else return 0;
      */
     }
    };

  47. class ChicagoPizzaStore : public PizzaStore {
     Pizza *createPizza(string item)
     {
             if (item == "cheese" )
                  return new ChicagoStyleCheesePizza;
     /*
             else if (item == "veggie")
                  return new ChicagoStyleVeggiePizza;
             else if (item == "clam")
                  return new ChicagoStyleClamPizza;
             else if (item == "pepperoni")
                  return new ChicagoStylePepperoniPizza;
             else return 0;
       */
     }
    };

  48. int main()
    {
     PizzaStore *nyStore = new NYPizzaStore;
     PizzaStore *chicagoStore = new ChicagoPizzaStore;
  49.  Pizza *pizza = nyStore->orderPizza("cheese");
     cout << "Ethan ordered a " + pizza->getName() << endl;
  50.  pizza = chicagoStore->orderPizza("cheese");
     cout << "Joel ordered a " + pizza->getName() << endl;
  51.  return 0;
    }
    #endif

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

History

Last edited on 01/01/2008 23:15 by jinsu56

Comments (0)

You must log in to leave a comment. Please sign in.