팩토리 패턴

* Simple factory


kimbob 가게를 생각해보자. 주문을 하면 김밥객체를 받아 재료를 준비하고 만들고 돌돌말아 자른뒤 포장한다고 가정해보자. 이를 코드로 보면 아래와 같다.

Kimbob orderKimbob() {
 Kimbob kimbob = new Kimbob();
 
 kimbob.prepare();
 kimbob.make();
 kimbob.roll();
 kimbob.cut();
 kimbob.box();
}
kimbob 가게의 김밥이 한줄 뿐이겠는가? 여러 김밥이 존재할 수 있다.

Kimbob orderKimbob(String type) {
 Kimbob kimbob;
 
 if(type.equals("normal")) {
  kimbob = new Kimbob();
 }
 else if(type.equals("tuna")) {
  kimbob = new TunaKimbob();
 }
 else if(type.equals("kimchi")) {
  kimbob = new KimchiKimbob();
 }
 
 Kimbob kimbob = new Kimbob();
 
 kimbob.prepare();
 kimbob.make();
 kimbob.roll();
 kimbob.cut();
 kimbob.box();
}

제일 중요한 디자인 원칙 중 하나는 변경되는 부분을 변경되지 않는 부분과 분리하여 캡슐화 하는 것이다. 위 예를 보면 변경되는 부분은 김밥 객체를 받는 부분이다. 일단 객체만 받으면 준비,만들기,말기,자르는 기능들은 변하지 않는다.

그럼 위에서 변경되는 부분을 factory라는 객체로 캡슐화 시켜보자


public class SimpleKimbobFactory {
 public Kimbob createKimbob(String type) {
  Kimbob kimbob = null;
  
  if(type.equals("normal")) {
   kimbob = new Kimbob();
  }
  else if(type.equals("tuna")) {
   kimbob = new TunaKimbob();
  }
  else if(type.equals("kimchi")) {
   kimbob = new KimchiKimbob();
  }
  
  return kimbob
 }
}

이렇게 변경할 경우 무엇이 좋은거지? 궁금증이 들 수 있다. kimbob 객체의 생성을 배달, 가격, 설명 등의 기능에서 필요하다고 하면, factory로 캡슐화한 클래스만 변경하면 된다.


* factory 메소드 패턴

위의 김밥집이 잘되어 중국과 일본에도 진출되었다고 생각해보자. 기존의 simple factory를 제거하고 아래와 같이 factory를 만들 수 있다.

ChinaKimbobFactory cFactory = new ChinaKimbobFactory();
KimbobStore chinakimbobStore = new KimbobStorecFactory();
chinakimbobStore.orderKimbob('tuna');

JapanKimbobFactory jFactory = new JapanKimbobFactory();
KimbobStore japankimbobStore = new KimbobStorecFactory();
japankimbobStore.orderKimbob('kimchi');

이렇게 적용해보니 나라마다 만드는 방식이 조금씩 달라 문제가 발생했다. (책에서 이와 같은 형식으로 설명하는데 뭐가 문제인지 잘 이해가 안간다 똑똑하고 싶어...)

이때 김밥을 만드는 활동은 KimbobStore 클래스에 국한시키면서, 나라마다 고유의 스타일을 살릴 수 있는 방법이 있다. factory 패턴을 적용하는 것이다. 정의는 뒤에서 하고 먼저 아래를 보자.

createKimbob 메소드를 kimbobStore에 다시 집어놓고 추상메소드로 선언한다. 각 나라에서는 고유의 스타일에 맞게 메소드를 정의할 것이다.

public abstract class KimbobStore{

 public Kimbob orderKimbob(String type) {
  Kimbob kimbob;
  kimbob = createKimbob(type);

  kimbob.prepare();
  kimbob.make();
  kimbob.roll();
  kimbob.cut();
  kimbob.box();

  return kimbob;
 }
 protected abstract Kimbob createKimbob(String type);
} 
추상화 메소드 createKimbob 선언하고 KimbobStore의 서브클래스 JapanKimbobFactory, ChinaKimbobFactory에서 createKimbob 메소드를 각 나라 스타일에 맞게 정의하면 된다.

 팩토리 메소드 패턴에서는 객체의 생성을 캡슐화 한다. 그리고 서브 클래스에서 어떤 객체를 만들지를 결정한다.

위의 Simple factory 부터 정리해보면 객체의 생성이 변경되는 부분일 때, 이를 캡슐화하고 어떤 객체가 만들어질지는 서브클래스에서 결정하게 되면 factory 메소드 패턴을 쓴다고 볼 수 있다.

댓글 없음:

댓글 쓰기