본문 바로가기

💻 개발IT/Design Patterns

4. Creational 패턴 - Factory Method Pattern

Creational 패턴

 

Object 생성할 때, interface로 코딩하게 될 텐데..

만약 목적에 따라서 다른 duck을 만들어야한다면 아래와 같이 분기문을 만들 수 있다.

하지만 이 client는 concrete class명(MallardDuck, DecoyDuck, RubberDuck...)에 dependency를 가지게 된다.

그렇게 된다면 이 코드는 class 추가 및 변경에 대한 영향을 받게 된다.

 

client 코드 수정 없이 다른 object들을 instantiate하기 위해..

new를 안 쓰는 방법은 없을까?

 

Creational 패턴이 new 연산자를 대신하는 패턴이다.

 

 

 

문제 정의

피자를 주문하는 class를 만들어본다고 하자.

 

그릭 피자가 너무 안 팔려서 다른 피자로 변경하고자 한다.

그러면 그릭피자 자리에 다른 피자 class를 생성하여 new를 해주게 된다.

 

하지만, 그 외 하단의 함수(prepare, bake, cut, box)들은 변경되지 않는다.

자주 변경하는 부분과 변경되지 않는 부분이 함께 있다면 좋은 로직이 아니기 때문에(디자인 패턴 사용) 분리를 해야 한다.

 

 

해결 방법 1 (Simple Factory)

 

피자 생성만 전문적으로 하는 class를 분리하여 생성한다.

타입에 맞는 피자 생성을 factory에 위임한다.

이제 피자 타입이 변경되어도 client코드 내 orderPizza는 변경할 필요가 없다. (dependency가 사라졌다)

 

만약 다양한 피자 지점이 있어서 이에 맞춰 많은 피자 factory가 생성되게 된다.

 

이렇게 되면, 아래처럼 store와 해당 store에서 제공하는 pizza가 따로 놀 수 있게 되어

(A store인데 B pizza factory를 이용하여 다른 피자를 만들어낼 수 있다!)

이를 체계적으로 만들어보자.

 

 

해결 방법 2 (Factory Method)

피자 Store의 프레임워크를 만들어준다 (abstract로 생성)

createPizza를 abstract method로 생성하여 하위 class가 생성할 수 있게 만든다.

 

잘못된 설계 (Factory Method)

자신이 만들 Pizza를 직접적으로 호출하고 있다. 

Pizza에 대한 property을 바꾸거나 새로운 Pizza를 생성하고자 하면 PizzaStore는 항상 영향을 받게 된다.

PizzaStore가 직접적인 영향을 받지 않기 위해 Pizza라는 abstract class가 필요한다.

 

 

Factory Method Pattern

상속을 사용하여 하위 class가 어떤 객체를 만들지 결정하는 패턴

 

client는 하위 class가 factory method를 오버라이드할 수 있도록 하여

직접적인 사용자(하위 class)가 무엇을 할지 결정할 수 있도록 한다.

 

그러나 런타임에 Product을 변경할 수 있지는 않다.

반응형