팩토리 메소드 패턴은 부모(상위) 클래스 코드에 구체 클래스 이름을 감추고, 자식(하위) 클래스가 어떤 객체를 생성할지를 결정하도록 하는 패턴이다.
구체적인 객체 생성 과정을 추상화한 인터페이스를 제공한다는 점에서 추상 팩토리 패턴과 비슷하지만 추상 팩토리 패턴은 관련있는 여러 객체를 구체적인 클래스에 의존하지 않고 만들 수 있게 해주는 것이 목적이고, 팩토리 메소드 패턴은 구체적인 객체 생성 과정을 하위 또는 구체적인 클래스로 옮기는 것이 목적이라는 점에서 다르다.
'확장에 대해 열려있고 수정에 대해 닫혀있어야 한다'는 개방-폐쇄 원칙(OCP)을 만족하는 객체 생성 방법이다.
@Getter
@Setter
@NoArgsConstructor
public abstract class Pizza {
String name;
String topping;
String sauce;
}
public class CheesePizza extends Pizza{
public CheesePizza() {
super();
this.setName("Cheese pizza");
this.setSauce("Cheese sauce");
this.setTopping("Cheese");
}
}
public class PineapplePizza extends Pizza {
public PineapplePizza() {
super();
this.setName("Pineapple pizza");
this.setSauce("Pineapple sauce");
this.setTopping("Pineapple");
}
}
추상 클래스 Pizza와 그 클래스를 상속받은 CheesePizza, PineapplePizza가 있다.
public enum PizzaType {
CHEESE,
PINEAPPLE
}
어떤 타입(클래스)의 피자를 생성할지 정확하게 입력받기 위해 enum 클래스를 만든다. (선택사항임)
@NoArgsConstructor
public class PizzaFactory {
public Pizza createPizza(PizzaType pizzaType){
switch (pizzaType) {
case CHEESE:
return new CheesePizza();
case PINEAPPLE:
return new PineapplePizza();
}
return null;
}
}
enum 값을 입력받아 각각 다른 클래스의 피자를 반환하는 팩토리 클래스를 만든다. 이렇게 하면 메인 클래스에서 자세한 피자 종류 클래스를 정해주지 않고 구체 클래스 객체를 생성할 수 있다. 클라이언트는 Pizza Interface를 사용해서 로직을 구현하면 된다.
이 링크로 가면 코드를 볼 수 있다.