팩토리 메소드 패턴 (Factory Method Pattern)

종명·2021년 4월 25일
1

헤드 퍼스트 디자인 패턴을 읽고 정리한 글입니다.

팩토리 메소드 패턴(Factory Method Pattern)은 객체를 생성하기 위해 인터페이스를 만듭니다. 어떤 클래스의 인스턴스를 만들지를 서브클래스에서 결정하도록 합니다. 팩토리 메소드를 이용하면 인스턴스를 만드는 일을 서브클래스로 미룰 수 있습니다.

https://ko.wikipedia.org/wiki/%ED%8C%A9%ED%86%A0%EB%A6%AC%EB%A9%94%EC%84%9C%EB%93%9C%ED%8C%A8%ED%84%B4

예제 코드

다음은 피자를 주문하는 예제입니다.

먼저 Creator 클래스인 PizzaStore를 만든다. 이 클래스는 createPizza라는 팩토리 메소드를 실행해서 pizza를 생성한다.

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);
}

PizzaStore를 확장해 각 지점을 만들고 지점마다 피자를 만드는 것을 책임지도록 createPizza 팩토리 메소드를 오버라이딩한다.

public class NYPizzaStore extends PizzaStore {
    @Override
    Pizza createPizza(String item) {
        if ("cheese".equals(item)) {
            return new NYStyleCheesePizza();
        } else if ("veggie".equals(item)) {
            return new NYStyleVeggiePizza();
        } else if ("clam".equals(item)) {
            return new NYStyleClamPizza();
        } else {
            return null;
        }
    }
}
public class ChicagoPizzaStore extends PizzaStore {
    @Override
    Pizza createPizza(String item) {
        if ("cheese".equals(item)) {
            return new ChicagoStyleCheesePizza();
        } else if ("veggie".equals(item)) {
            return new ChicagoStyleVeggiePizza();
        } 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;
    }
}

Product 클래스인 Pizze 를 확장해 3가지 시카고 스타일 피자를 만들었다. (뉴욕 스타일 피자 코드는 생략하였다)

public class ChicagoStyleCheesePizza extends Pizza {
    public ChicagoStyleCheesePizza() {
        name = "ChicagoStyleCheesePizza";
    }
}
public class ChicagoStyleClamPizza extends Pizza {
    public ChicagoStyleClamPizza() {
        name = "ChicagoStyleClamPizza";
    }
}
public class ChicagoStyleVeggiePizza extends Pizza {
    public ChicagoStyleVeggiePizza() {
        name = "ChicagoStyleVeggiePizza";
    }
}

이제 main 메소드에서 예제를 실행해보자.

PizzaStore nyStore = new NYPizzaStore();
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~~ NYStyleCheesePizza
baking~~
boxing~~
preparing~~ NYStyleClamPizza
baking~~
boxing~~
preparing~~ ChicagoStyleCheesePizza
baking~~
boxing~~
preparing~~ ChicagoStyleClamPizza
baking~~
boxing~~

지점과 주어진 타입(cheeze, clam)에 따라 다른 피자를 만드는 걸 볼 수 있다.

0개의 댓글