Design Pattern

04. Factory Method Pattern

kangwook 2022. 8. 18. 23:17
객체 생성 처리를 서브 클래스로 분리해서 처리하도록 캡슐화하는 패턴

Factory Method Pattern

Factory Method Pattern은 객체를 생성하기 위한 인터페이스를 정의하지만, 하위 클래스가 인스턴스화할 클래스를 결정할 수 있다. 즉, Factory Method를 활용하면 클래스가 인스턴스화 하는 것을 하위 클래스로 연기할 수 있다.

  • Product : 팩토리 메서드로 생성될 객체의 공통 클래스
  • ConcreteProduct : 구체적으로 객체가 생성되는 클래스
  • Creator(Factory) : Product타입을 반환하는 팩토리 메서드를 갖는 클래스
  • ConcreteCreator(ConcreteFactory) : 팩토리 메서드를 구현하는 클래스

Factory Method Pattern 예제

  • 피자를 주문하는 예제
    • Creator인 PizzaStore를 만든 후
    • NewYorkPizzaStore, ChicagoPizzaStore 구현
    • 그 다음 Product인 Pizza 클래스를 만들고 확장해서
    • 구체적 클래스인 ChicagoStyleCheesePizza, ChicagoStyleClamPizza, NewYorkStyleCheesePizza, NewYorkStyleClamPizza를 구현

  • Creator : PizzaStore 클래스
public abstract class PizzaStore {
    public Pizza orderPizza(String type) {
        Pizza pizza = createPizza(type);
        pizza.prepare();
        pizza.bake();
        pizza.box();
        return pizza;
    }
     
    abstract Pizza createPizza(String type);
}
  • ConcreteCreator : NewYorkPizzaStore, ChicagoPizzaStore 클래스
    • 추상 클래스인 createPizza 메서드 구현
public class NewYorkPizzaStore extends PizzaStore {
    Pizza createPizza(String item) {
        if("cheese".equals(item)) {
            return new NewYorkStyleCheesePizza();
        } else if ("clam".equals(item)) {
            return new NewYorkStyleClamPizza();
        } else {
            return null;
        }
    }
}
 
public class ChicagoPizzaStore extends PizzaStore {
    Pizza createPizza(String item) {
        if("cheese".equals(item)) {
            return new ChicagoStyleCheesePizza();
        } else if ("clam".equals(item)) {
            return new ChicagoStyleClamPizza();
        } else {
            return null;
        }
    }
}
  • Product : Pizza 클래스
public abstract class Pizza {
    String name;
    String dough;
    String sauce;
 
    void prepare() {
        System.out.println("preparing~~ " + name);
    }
     
    void bake() {
        System.out.println("baking~~");
    }
 
    void box() {
        System.out.println("boxing~~");
    }
 
    public String getName() {
        return name;
    }
}
  • ConcreteProduct : NewYorkStylePizzaStore, ChicagoStylePizzaStrore 클래스
    • Product 클래스인 Pizza를 확장해 각각 2가지 스타일의 피자를 만듦
public class ChicagoStyleCheesePizza extends Pizza {
    public ChicagoStyleCheesePizza() {
        name = "ChicagoStyleCheesePizza";
    }
}
 
public class ChicagoStyleClamPizza extends Pizza {
    public ChicagoStyleClamPizza() {
        name = "ChicagoStyleClamPizza";
    }
}
 
public class NewYorkStyleCheesePizza extends Pizza {
    public NewYorkStyleCheesePizza() {
        name = "NewYorkStyleCheesePizza";
    }
}
 
public class NewYorkStyleClamPizza extends Pizza {
    public NewYorkStyleClamPizza() {
        name = "NewYorkStyleClamPizza";
    }
}
  • Main 함수
PizzaStore nyStore = new NewYorkPizzaStore();
PizzaStore chicagoStore = new ChicagoPizzaStore();
 
Pizza nyCheesePizza = nyStore.orderPizza("cheese");
Pizza nyClamPizza = nyStore.orderPizza("clam");
 
Pizza chicagoCheesePizza = chicagoStore.orderPizza("cheese");
Pizza chicagoClamPizza = chicagoStore.orderPizza("clam");

출력결과

preparing~~ NewYorkStyleCheesePizza
baking~~
boxing~~
preparing~~ NewYorkStyleClamPizza
baking~~
boxing~~
preparing~~ ChicagoStyleCheesePizza
baking~~
boxing~~
preparing~~ ChicagoStyleClamPizza
baking~~
boxing~~

결론

  • Factory Method Pattern은 객체의 생성 처리를 서브 클래스로 분리하여 처리하는 생성 패턴(Creational Pattern)
  • 장점
    • 객체들을 한 곳에서 관리할 수 있음
    • 객체의 생명주기를 관리하기 쉬워짐
    • 기존 소스코드를 변경할 필요없이 새로운 하위 클래스를 만들면 되기 때문에 유연한 구조가 됨
  • 단점
    • 계속해서 새로운 하위 클래스를 정의하기 때문에 불필요하게 많은 클래스를 정의할 수도 있음 → 복잡해질 수 있음

본문은 Head First Design Pattern (2004) 를 참고하여 공부하고 작성하였음