2010년 1월 25일 월요일

간단한 팩토리(Simple Factory)

 

간단한 팩토리(Simple Factory)

  간단한 팩토리는 디자인 패턴이라고 할 수는 없지만 프로그래밍을 하는데 있어서

자주 쓰이는 관용구에 가깝다.


new의 문제점

  "new"는 “구상 객체”를 뜻함

  new를 사용하는 것은 구상 클래스의 인스턴스를 만드는 것으로 구상 클래스를 바탕으로

코딩을 하면 나중에 코드를 수정해야 할 가능성이 높아지고 유연성이 떨어지게 됨


Pizza orderPizza(){

 Pizza pizza = new Pizza();

 // 유연성을 감안하여 추상 클래스 또는 인터페이스로 만드는 것이 좋지만 추상클래스나

 // 인터페이스로는 직접 인스턴스를 만들 수 없음

 

 pizza.prepare();

 pizza.bake();

 pizza.cut();

 pizza.box();

 return pizza;

}


1. 피자 종류를 고르고 피자를 만들기 위한 코드의 추가


Pizza orderPizza(String type){  // orderPizza메소드의 인자로 피자 종류를 전달

 Pizza pizza = new Pizza();

 

 if (type.equals("cheese")){

  pizza = new CheesePizza();

 } else if (type.equals("greek")){

  pizza = new GreekPizza();

 } else if (type.equals("pepperoni"){

  pizza = new PepperoniPizza();

 }

//  피자 종류를 바탕으로 올바른 구상 클래스의 인스턴스를 만들고 pizza인스턴수 변수에 그 인스턴스를 대입. 여기에 있는 모든 피자 클래스는 pizza인터페이스를 구현


 pizza.prepare();

 pizza.bake();

 pizza.cut();

 pizza.box();

 return pizza;

}



2. 피자 종류를 추가 해야 할 때

Pizza orderPizza(String type){  // orderPizza메소드의 인자로 피자 종류를 전달

 Pizza pizza = new Pizza();

 

////// 바뀌는 부분으로 피자 종류가 바뀔때마다 코드를 수정해야 함/////////

 if (type.equals("cheese")){

  pizza = new CheesePizza();

 } else if (type.equals("greek")){

  pizza = new GreekPizza();

 } else if (type.equals("pepperoni"){

  pizza = new PepperoniPizza();

 } else if (type.equals("clam"){

  pizza = new PepperoniPizza();

 } else if (type.equals("veggie"){

  pizza = new PepperoniPizza();

 }

 // 이 코드는 코드 변경에 대해 닫혀있지 않기 때문에 피자가게에서 메뉴를 변경하려면 이코드를 직접 고쳐야 함

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


//////////////// 바뀌지 않는 부분/////////////////////

 pizza.prepare();

 pizza.bake();

 pizza.cut();

 pizza.box();

 return pizza;

////////////////////////////////////////////////////////////

}


3. 객체 생성 부분을 캡슐화

Pizza orderPizza(){

 Pizza pizza;

 

 // 바뀌는 객체 생성 코드를 orderPizza 메소드에서 빼냄


 pizza.prepare();

 pizza.bake();

 pizza.cut();

 pizza.box();

 return pizza;

}


4. 피자를 만들기 위한 객체 생성 부분을 전담할 간단한

피자 팩토리 클래스


public class SimplePizzaFactory{

 public Pizza createPizza(String type){

 // createPizza() 메소드를 정의. 이 메소드는 클라이언트에서 새로운 객체의 인스턴스를 만들때 호출하는 메소드

  Pizza pizza = null;


  if (type.equals("cheese")){

   pizza = new CheesePizza();

  } else if (type.equals("pepperoni"){

   pizza = new PepperoniPizza();

  } else if (type.equals("clam"){

   pizza = new PepperoniPizza();

  } else if (type.equals("veggie"){

   pizza = new PepperoniPizza();

  }

  return pizza;

 }

}


5. 팩토리를 이용해서 피자 객체를 생성하도록 수정

public class PizzaStore{

 SimplePizzaFactory factory;

 // PizzaStore에 SimplePizzaFactory에 대한 레퍼런스를 저장

 public PizzaStore(SimplePizzaFactory factory{

 // PizzaStore의 생성자에 팩토리 객체가 전달

  Pizza pizza;


  pizza = factory.createPizza(type);

  // new 연산자 대신 팩토리 객체에 있는 create메소드를 사용

  pizza.prepare();

  pizza.bake();

  pizza.cut();

  pizza.box();

  return pizza;

 }

 // 기타 메소드

}

 

<최종의 클래스 다이어그램>



  디자인 패턴에 대해 이야기할 때 “인터페이스를 구현한다”는 표현이 나온다고 해서 항상

“클래스를 선언하는 부분에서 implements 키워드를 써서 어떤 자바 인터페이스를 구현하는 클래스를 만든다”라고 생각하면 안됨. 일반적으로 어떤 상위 형식(클래스 일수도 있고

인터페이스 일 수도 있음)

 

출처 : Head First Design Patterns

댓글 없음:

댓글 쓰기