ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 심플팩토리 패턴 -> 팩토리 메소드 패턴 이야기
    @ 16. 1 ~ 17. 1/디자인 패턴 2015. 2. 1. 22:14

    #include<iostream>
    #include<conio.h>
    #include<memory>
    #include<vector>
    #include<algorithm>
    #include<string>

    using namespace std;

    class Pizza
    {
    public:
     string name;
    public:
     virtual void prepare()
     {
      cout << name.c_str() << "피자 준비중"<<endl;
     }
     virtual void back()
     {
      cout <<"피자 굽기"<<endl;
     }
     virtual void cut()
     {
      cout <<"피자 자르기"<<endl;
     }
     virtual void box()
     {
      cout <<"피자 포장하기"<<endl;
     }
    };

    class CheesePizza : public Pizza
    {
    public:
     CheesePizza()
     {
      name="치츠";
     }
     virtual void cut()
     {
      Pizza::cut();
      cout << "자르다 다시 붙음"<<endl;
     }
    };

    class VeggiePizza : public Pizza
    {
    public:
     VeggiePizza()
     {
      name="야채";
     }
    };

    class SimplePizzaFactory
    {
    public:
     shared_ptr<Pizza> pizza;
    public:
     SimplePizzaFactory() : pizza(NULL)
     {

     }
     ~SimplePizzaFactory()
     {
     }
     shared_ptr<Pizza> createPizza(string type)
     {
      if(type=="cheese")
      {
       pizza=(shared_ptr<Pizza>(new CheesePizza));
      }
      else if(type=="veggie")
      {
       pizza=(shared_ptr<Pizza>(new VeggiePizza));
      }
      return pizza;
     }
    };

    class PizzaStore
    {
    public:
     shared_ptr<SimplePizzaFactory> factory;
     shared_ptr<Pizza> pizza;
    public:
     PizzaStore(shared_ptr<SimplePizzaFactory> factory)
     {
      this->factory=factory;
     }
     shared_ptr<Pizza> orderPizza(string type)
     {
      pizza=factory->createPizza(type);
      pizza->prepare();
      pizza->back();
      pizza->cut();
      pizza->box();
      return pizza;
     }
    };

    int main()
    {
     shared_ptr<SimplePizzaFactory> Simple(new SimplePizzaFactory);
     PizzaStore a(Simple);
     shared_ptr<Pizza> pizza=a.orderPizza("cheese");
     getch();
     return 0; 
    }

     

    pizzastore는 팩토리를 사용하는 클라이언트

    (simplefactory를 통해 피자 인스턴스를 받는다.)

     

    simplefactory 피자 객체를 생성하는 팩토리 유일하게 구상 pizza 클래스를 직접참조함(new한다고)

     

    pizza 팩토리에서 만들어내는 피자

     

    cheesepizza pizza를 상속받은 세부메뉴

     

     

    간단히 이야기해서 심플팩토리를 통해서 pizzastore에서 피자를 만든다는것.

    SimplePizzaFactory 객체를 만들고 PizzaStore 객체에 인자로 던집니다. PizzaStore 객체의 orderPizza() 메서드를 이용해 피자를 만듬

     

    근데 만약에 지역별로 입맛이 반영된 피자를 만들어야 한다면..?

    simplefactory를 빼고

    nypizzafactory, chicagopizzafactory를 만들고 pizzastore에 적당한 팩토리를 사용하도록 분점을 만들면..?

    이거 어디서 많이 봤지?? 아 stragey 패턴..ㅎ

     

    위에

     shared_ptr<SimplePizzaFactory> Simple(new SimplePizzaFactory);
     PizzaStore a(Simple);
     shared_ptr<Pizza> pizza=a.orderPizza("cheese");

    부분이 어떻게 바뀌냐면..

     

     shared_ptr<nyPizzaFactory> nysimple(new nyPizzaFactory);
     PizzaStore a(nysimple);
     shared_ptr<Pizza> pizza=a.orderPizza("cheese");

     

    이런식으로 chicagopizza도..

     

    근데 지역이 틀린 피자다보니까.위 처럼. 이렇게 만들긴 하는데..굽는 방식이나 자르는 방식, 상자에 포장하는 방식이틀리다면..?

     

    그러면 피자가게와 피자 제작과정을 묶어주는게 낫지 않나? 프레임워크

    opderpizza 메소드는 이미 주문 시스템으로써 잘 갖춰져있어서 모든 분점에서 똑같이 진행되야함.(건들지마라)

    즉 ny피자는 빵이 얇고 chicago는 두껍고 이런거..

     

    그러면 피자 만드는과정을 가게에 넣어보자

     

    createPizza메소드를 pizzastore에 넣는데 추상메소드로 넣는다.

    각 지역마다 고유의 스타일에 맞게 pizzastore의 서브클래스를 만들것임..

    class PizzaStore
    {
    public:
     shared_ptr<Pizza> pizza;
    public:
     PizzaStore()
     {
     }
     virtual shared_ptr<Pizza> createPizza(string type)=0; //추상메소드
     shared_ptr<Pizza> orderPizza(string type)
     {
      pizza=createPizza(type); //팩토리 create 대신 추상메소드 createPizza호출
      pizza->prepare();
      pizza->back();
      pizza->cut();
      pizza->box();
      return pizza;
     }
    };

    이런식으로 바뀌고..

    각 지역마다 고유의 스타일에 맞게 서브클래스가 필요함..

    (nypizzastore, chicagopizza store)

     

    피자스타일은 각 지역마다의 서브클래스의 createPizza()에서 결정하고 책임질것임..(추상메소드이니까? 상속받고..)

    (pizzastore의 서브클래스에서 createPizza를 구현해야해..안하고 싶어? 추상ㅅ메소드인게데?)

    즉, 위에서 simplefactory에서 작성한 createpizza가 들어간다고 보면됨..

     if(type=="cheese")
      {
       pizza=(shared_ptr<Pizza>(new NYCheesePizza));
      }
      else if(type=="veggie")
      {
       pizza=(shared_ptr<Pizza>(new NYVeggiePizza));
      }

    그래서 서브클래스에서 작성되는 createPizza 메소드를 팩토리 메소드라 불리기도 함..

    왜냐면 객체 생성을 처리하고 객체 생성을 하는 작업을 서브클래스에 캡슐화 시킬 수 있으니..

    *팩토리 메소드에서 리턴하는 객체는 보통 슈퍼클래스에서 정의한 메소드에서 쓰이게 된다.

    (위에 피자 예에서는 pizza가 리턴되고 pizza.order를 하지요.)

     

    결론

    팩토리 메소드 패턴은

    객체를 생성하기 위한 인터페이스를 정의하는ㄷ(Pizzastore) 어떤 클래스의 인스턴스를 만들지는 서브클래스에서 결정하게 만든다.(nypizzastore) 팩토리 메소드 패턴을 이용하면 클래스의 인스턴스를 만드는 일을 서브클래스에게 맡기는 것.

     

    '@ 16. 1 ~ 17. 1 > 디자인 패턴' 카테고리의 다른 글

    객체 풀  (0) 2016.12.26
    컴퍼넌트 패턴 & 이벤트 큐 정리  (0) 2016.12.26
    중재자 패턴  (0) 2016.02.01
Designed by Tistory.