Pizza orderPizza(String type) {
Pizze pizza;
if (type.equals("cheese")) {
pizza = new CheesePizza();
} else if (type.equals("pepperoni")) {
pizza = new PepperoniPizza();
}
pizza.bake();
}
피자가게에서 피자 주문을 처리하는 로직이다. 여기서 신메뉴가 추가된다고 했을 때, type에 따라 피자를 생성하는 if-else 구문이 변경되어야 한다.
팩토리: 객체 생성을 처리하는 클래스
# 팩토리
public class SimplePizzaFactory {
public Pizza createPizza(String type) {
Pizza pizza = null;
if (type.equals("cheese")) {
pizza = new CheesePizza();
} else if (type.equals("pepperoni")) {
pizza = new PepperoniPizza();
}
}
}
# 클라이언트
public class PizzaStore {
SimplePizzaFactory factory;
public PizzaStore(SimplePizzaFactory factory) {
this.factory = factory;
}
public Pizza orderPizza(String type) {
Pizza pizza = null;
pizza = factory.createPizza(type);
pizza.bake();
}
}
orderPizza()에서 직접 구상 클래스의 인스턴스를 만들지않고 팩토리를 사용하도록 수정했다.
만약 PizzaStore가 아니라 다른 곳에서도 인스턴스 생성 코드가 필요할 때 인스턴스 생성 부분이 바뀌더라도 팩토리 클래스만 수정하면 된다.
이와 같이 간단한 팩토리의 경우 createPizza를 정적 메서드로 선언하여 정적 팩토리로 만들어 사용하는 경우가 많다.
지역별 피자가게가 생긴다고 가정해서 간단한 팩토리를 적용시킨 코드는 다음과 같다.
NYPizzaFactory nyFactory = new NYPizzaFactory();
PizzaStore nyStore = new PizzaStore(nyFactory);
nyStroe.orderPizza("Cheese");
ChicagoPizzaFactory chicagoFactory = new ChicagoPizzaFactory();
PizzaStore chicagoStore = new PizzaStore(chicagoFactory);
chicagoStore.orderPizza("Cheese");
이 경우에 피자 인스턴스는 팩토리를 통해 생성하지만 피자를 만드는 과정은 제각각 달라질 수 있다. 따라서 PizzaStore와 피자 제작 코드를 묶는 작업이 필요하다.
public abstract class PizzaStore {
public Pizza orderPizza(String type) {
Pizza pizza;
pizza = createPizza(type);
pizza.bake();
return pizza;
}
abstract Pizza createPizza(String type);
}
각 지점은 PizzaStore의 서브클래스를 만들고 createPizza 메서드를 오버라이드한다.
public class NYStylePizzaStore extends PizzaStore {
public Pizza createPizza(String type) {
if (type.equals("cheese")) {
return new NYStyleCheesePizza();
} else if (type.equals("pepperoni")) {
return new NYStylePepperoniPizza();
} else {
return null;
}
}
}
public class ChicagoStylePizzaStore extends PizzaStroe {
public Pizza createPizza(String type) {
if (type.equals("cheese")) {
return new ChicagoStyleCheesePizza();
} else if (type.equals("pepperoni")) {
return new ChicagoStylePepperoniPizza();
} else {
return null;
}
}
}
추상 생산자 클래스(PizzaStore)