Skip to content

Factory Method Pattern

Glory Day edited this page Jun 16, 2022 · 9 revisions

About

객체를 생성 처리를 서브 클래스로 분리해 처리하도록 캡슐화하는 패턴이다.
즉, 객체의 생성 코드를 별도의 클래스/메소드로 분리함으로써 객체 생성의 변화에 대비하는데 유용하다.

UML Class

UML_Class_1

팩토리 메소드 패턴 UML 클래스


  • Creator : factoryMethod()를 갖는 클래스.
  • Product : factoryMethod()로 생성될 객체의 공통 인터페이스.
  • ConcreteCreator : factoryMethod()를 구현하는 클래스로 ConcreteProduct 객체를 생성.
  • ConcreteProduct : 구체적으로 객체가 생성되는 클래스.

Example

피자 가게를 운영하는 객체를 구현하려 한다. 피자 가게에는 여러 피자를 판매한다.

Pizza* orderPizza(string pizza) {
    Pizza* pizza;

    if (type == "cheese") {
        pizza = new CheesePizza();
    }
    else 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();
    }

    pizza.prepare();
    pizza.bake();
    pizza.cut();
    pizza.box();

    return pizza;
}

Problem

orderPizza() 메소드의 가장 큰 문제점은 인스턴스를 만드는 구상 클래스를 선택하는 부분이다. 위 부분 때문에 상황이 변화면 코드를 변경해야 한다.
따라서 위 부분을 캡슐화해야 한다.

UML_Class_2

간단한 팩토리 UML 클래스


위의 피자 가게를 각각 뉴욕과 시카고에 지점을 놓는다 가정한다. 각 지역마다 고유의 스타일의 피자를 만드는 방법이 있다.

NYPizzaFactory* nyFactory = new NYPizzaFactory();
PizzaStore* nyStore = new PizzaStore(nyFactory);
nyStore->orderPizza("veggie");

ChicagoPizzaFactory* chicagoFactory = new ChicagoPizzaFactory();
PizzaStore* chicagoStore = new PizzaStore(chicagoFactory);
chicagoStore->orderPizza("veggie");

문제는 각 피자를 만드는 방법이 다른 것에서 시작된다. 위의 객체에는 유연성이 전혀 없다.
피자 가게와 피자 만드는 방법을 하나로 묶는 좋은 방법이 필요하다.

Solution

UML_Class_3

개선된 피자 가게 UML 클래스


PizzaStore 클래스의 createPizza() 메소드를 추상메소드로 선언한다. 이제 각 지역마다 createPizza() 메소드를 구현해서 생성하는 객체를 다르게 할 수 있다.
orderPizza() 메소드는 PizzaStore 클래스 내에 구현이 되어있다. 또한 어떤 종류의 피자를 받는지는 orderPizza() 메소드는 확인할 수 없다. 피자의 종류는 어떤 서브 클래스를 선택했는지에 결정이 되고, orderPizza() 메소드는 그저 피자를 제조하는 역할만 담당한다.

위와 같은 구성으로 재사용이 가능한 프레임워크를 가질 수 있다.

Code

Clone this wiki locally