
구상 클래스에 의존하지 않고도 서로 연관되거나 의존적인 객체로 이루어진 제품군을 생상하는 인터페이스를 제공합니다. 구상 클래스는 서브클래스에서 만듭니다.
public interface PizzaIngredientFactory {
Dough createDough();
Sauce createSauce();
Cheese createCheese();
Veggies[] createVeggies();
Pepperoni createPepperoni();
public Clams createClam();
}
public class NYPizzaIngredientFactory implements PizzaIngredientFactory {
public Dough createDough() {
return new ThinCrustDough();
}
public Sauce createSauce() {
return new MarinaraSauce();
}
public Cheese createCheese() {
return new ReggianoCheese();
}
public Veggie[] createVeggies() {
return new Veggies[] { new Garlic(), new Onion(), new Mushroom() };
}
public Pepperoni createPepperoni() {
return new SlicedPepperoni();
}
public Clams createClam() {
return new FreshClams();
}
}
public class CheesePizza extends Pizza {
PizzaIngredientFactory ingredientFactory;
public CheesePizza(PizzaIngredientFactory ingredientFactory) {
this.ingredientFactory = ingredientFactory;
}
void prepare() {
dough = ingreedientFactory.createDough();
sauce = ingredientFactory.createSource();
cheese = ingredientFactory.createCheese();
}
}
위 코드들을 보면, PizzaIngredientFactory라는 제품군으로 피자를 생성하는 예제 코드입니다.
만약, 뉴욕 피자 재료(NYPizzaIngredientFactory)가 아닌 시카고 피자 재료로 피자를 만들어야 한다면, PizzaIngredientFactory를 구현한 ChicagoPizzaIngredientFactory를 구현하여 제공하면 됩니다.
위에서 설명한 장단점을 다시 한번 살펴보면

객체를 생성할 때 필요한 인터페이스를 만듭니다. 팩토리 메소드 패턴을 사용하면 클래스 인스턴스 만드는 일을 서브 클래스에세 맡기게 됩니다.
public abstract class PizzaStore {
public Pizza orderPizza(String type) {
Pizza pizza;
pizza = createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
abstract Pizza createPizza(String type);
}
public class NYPizzaStore extends PizzaStore {
Pizza createPizza(String item) {
if(item.equals("cheese") {
return NYCheesePizza();
} else if(item.equals("veggie")) {
return new NYVeggiePizza();
} else if(item.equals("calm") {
return new NYCalmPizza();
}
return null;
}
}
위에서 설명한 장단점을 다시 한번 살펴보면