본문 바로가기

ACC/디자인 패턴 스터디

[디자인 패턴 스터디] 4. 팩토리 패턴

 

 


세계적으로 유명한 피자 프랜차이즈의 피자 주문 시스템을 만든다고 생각해 보자. 가장 간단한 방법으로는 피자를 주문받는 클래스에서 피자의 종류를 확인하고, 그에 따라 피자를 만들고, 피자를 굽고 자르고 포장하는 식으로 코드를 작성하면 된다. 이렇게 만들면 당연히 문제가 있다. 지난번까지 배운 디자인 패턴에 위배가 되는 부분이 있다.

첫 번째로는 피자의 종류를 확인하고 피자를 만드는 과정에서 인터페이스에 맞춘 코딩이 아닌 구현을 이용하였다는 점이다.

두 번째로는 바뀌는 부분에 대해 캡슐화를 하지 않았다. 피자의 종류를 확인하는 과정은 아마도 ```if (type.equals("cheese pizza")```와 같이 조건문을 이용하여 구현할 수 있을 텐데 만약 피자의 종류가 새로 생기거나 삭제되는 일이 일어나면 코드를 변경해야 한다.

 

이를 해결하는 방법이 바로 팩토리다.

피자를 주문받는 클래스는 바뀔 수 있지 않은 부분인 피자를 준비하고, 굽고, 자르고, 포장하는 과정만 하고 바뀔 수 있는 부분인 피자의 종류를 확인하고 만드는 과정은 캡슐화하여 다른 클래스에 위임하는 것이다. 그리고 피자를 만드는 클래스를 팩토리 클래스라고 한다. 이렇게 되면 피자 클래스는 피자를 생성하는 클래스만 접근하여 만들어낼 수 있고 피자를 주문받는 클래스는 이를 이용하기만 하면 된다.

※ 이런 팩토리 클래스는 정적 메소드로 구현할 수도 있다. 객체를 만들지 않아도 된다는 장점이 있지만, 상속을 통한 행동의 변경은 불가능하다는 단점도 있다.

※ 이런 식의 Simple Factory는 디자인 패턴보다는 관용구에 가깝다고 한다.

 


하지만 이 피자 프랜차이즈는 세계적으로 유명하다. 전세계인들의 입맛에 맞춰야 한다. 마치 한국에서는 불고기 피자를 팔듯, 각 지역별로 스타일을 맞춰줘야 한다. 이를 해결하기 위해 가장 간단하게 접근하면, 각 지역 별로 하나씩 simple factory를 만들어주면 된다. 하지만 이렇게 하면 각 지역 별로 사용하는 factory가 다르기 때문에 피자를 주문하는 부분도 지역 별로 만들어줘야 하고 각 부분들이 따로 놀게 되어 피자를 자르지 않는다던지, 피자 상자가 이상하다던지 등의 문제가 생길 수 있다. 즉 피자를 주문하는(바뀌지 않는 부분)과 피자를 생성하는(팩토리) 부분이 묶여있어야 한다.

 

이를 해결하는 방법으로 추상 메소드를 사용한다. 팩토리 객체를 생성하지 않고 서브 클래스에서 따로 구현할 수 있는 추상 메소드를 만들어서 서브 클래스들이 자기들만의 피자 제조 방식을 구현하게 하면 된다.