Seoul-Transfer-Proj / design-pattern

C++로 디자인 패턴 구현해보며 이해하기 위한 레포
0 stars 0 forks source link

feat: 간단한 factory 개념 구현 #2

Closed changhwan77 closed 5 months ago

changhwan77 commented 5 months ago

아주 간단한 Factory 개념을 직접 구현해봤습니다.

[ 변경 전 ]

Pizza 클래스에서 orderPizza 메서드를 사용.

이 때 인자로 문자열 타입의 피자 타입을 받아 분기 처리를 통해 타입에 맞는 피자 객체를 생성해서 반환하였음.

Pizza Pizza::orderPizza (string type) {
  Pizza pizza;

  // type을 문자열로 받아서 그에 맞는 객체를 pizza 변수에 할당
  // 만약에 이외의 피자가 추가된다면?
  // ~
  if (type == "cheese") {
    pizza = CheesePizza();
  } else if (type == "greek")
  {
    pizza = GreekPizza();
  } else if (type == "pepperoni")
  {
    pizza = PepperoniPizza();
  }
  // 여기 부분을 하드 코딩해서 계속 바꿔줘야하는 단점이 있음. 

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

  return pizza;
}

[ 변경 후 ]

책 p.150에 따르면 다음과 같은 질문을 함.

image

  1. 따라서 구성(composition)과 인터페이스에 맞춘 코딩을 활용하려면 어떻게 할 수 있을까? 를 고민.
  2. 특히, 분기 처리(타입에 맞는 피자 객체 생성 및 반환)를 없애는 것에 집중.

[ main.cpp ]

int main() {
  // 치즈 피자 주문하기
  PizzaFactory* pizzaFactory = new CheesePizzaFactory();
  PizzaStore* pizzaStore = new PizzaStore(pizzaFactory);
  pizzaStore->orderPizza();

  // 시카고 피자 주문
  pizzaStore->setPizzaFactory(new ChicagoPizzaFactory());
  pizzaStore->orderPizza();

  // 뉴욕 피자 주문
  pizzaStore->setPizzaFactory(new NewYorkPizzaFactory());
  pizzaStore->orderPizza();
  delete pizzaStore;

  return 0;
};

[ 출력 결과 ] image

💡 아이디어: Factory를 인터페이스로 만들어 각 피자 타입을 만드는 객체 공장을 상속받아 사용해보면 어떨까? 에서 착안.

  1. PizzaStore에 구성을 활용해 PizzaFactory 타입의 포인터 변수를 선언.
  2. PizzaStore 객체 생성 시 생성자를 통해 만들고 싶은 피자 타입의 factory 객체를 new 키워드를 통해 생성.
  3. 피자 주문 시 PizzaStore의 orderPizza에서 인스턴스의 프로퍼티인 factory 객체의 주소에 접근해 생성자 호출.
  4. 다른 피자 주문 시 setPizzaFactory를 통해 PizzaStore에 관리하는 factory 객체를 바꿈.
    • 이 때, 메모리 누수를 방지하기 위해 setPizzaFactory에 넘겨준 factory 객체와 현재 인스턴스의 factory 객체가 다르다면 delete를 통해 객체 소멸 및 메모리 해제 시킴.
  5. factory가 원하는 피자로 바뀌면, orderPizza 메소드 활용해 피자 생성.
  6. 2 ~ 5 반복