[Design Pattern] 팩토리 메서드 패턴과 추상 팩토리 패턴
1. 간단한 팩토리
팩토리 메서드 패턴과 추상 팩토리 패턴을 알아보기 전에 우선, 팩토리가 무엇인지를 알아야합니다.
팩토리는 객체 생성을 처리하는 클래스를 일컫습니다.
아래 코드에서 객체를 생성하는 부분이 if~ else if 로 하드코딩되어 있는데, 이 부분을 팩토리로 뺄 수 있습니다.
public class PizzaStore {
Pizza orderPizza(String type) {
Pizza pizza;
// 아래 부분이 구체적인 객체를 생성하는 부분입니다.
// 객체를 생성하는 부분은 새로운게 추가되거나 없어지는 등 언제든 변할 수 있습니다.
if (type.equals("cheese")) pizza = new CheesePizza();
else if (type.equals("greekPizza")) pizza = new GreekPizza();
else if (type.equals("pepperoni")) pizza = new PepperoniPizza();
// 아래 부분은 변하지 않는 부분으로 볼 수 있습니다.
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
public interface Pizza {
void prepare(); // 피자 만들 준비
void bake(); // 피자 굽기
void cut(); // 피자 커팅
void box(); // 다 만든 피자 박스에 담기
}
public CheesePizza implements Pizza { ... }
public GreekPizza implements Pizza { ... }
public PepperoniPizza implements Pizza { ... }
피자 종류가 늘어날 때마다 위에서 else if문을 추가해줘야할까요?
이럴 때, 객체 생성을 처리하는 간단한 팩토리를 만들어 객체 생성을 분리할 수 있습니다.
public class SimplePizzaFactory {
public Pizza createPizza(String type) {
Pizza pizza = null;
if (type.equals("cheese")) pizza = new CheesePizza();
else if (type.equals("greekPizza")) pizza = new GreekPizza();
else if (type.equals("pepperoni")) pizza = new PepperoniPizza();
return pizza;
}
}
이제 위 팩토리를 사용하면 처음에 봤던 코드는 다음과 같은 모양을 가질 수 있습니다.
public class PizzaStore {
SimplePizzaFactory factory = new SimplePizzaFactory();
Pizza orderPizza(String type) {
Pizza pizza = factory.createPizza(type);
// 아래 부분은 변하지 않는 부분으로 볼 수 있습니다.
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
public interface Pizza {
void prepare(); // 피자 만들 준비
void bake(); // 피자 굽기
void cut(); // 피자 커팅
void box(); // 다 만든 피자 박스에 담기
}
public CheesePizza implements Pizza { ... }
public GreekPizza implements Pizza { ... }
public PepperoniPizza implements Pizza { ... }
2. 팩토리 메서드 패턴
위처럼 객체 생성을 위해 별도의 팩토리 클래스를 만들 수도 있지만, 메서드로도 만들어 줄 수 있습니다.
아래 코드를 보면 `createPizza()` 라는 추상 메서드를 두었고, 이 메서드는 객체 생성을 담당하는 팩토리 메서드입니다.
(팩토리라는 용어가 객체 생성과 동일한 의미라고 이해하시면 됩니다.)
public abstract class PizzaStore {
public Pizza orderPizza(String type) {
Pizza pizza = createPizza(type); // type에 대한 구체적인 피자 객체를 생성해서 반환한다.
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
// 객체 생성을 담당하는 팩토리 메서드를 추상 메서드로 정의한다.
public abstract Pizza createPizza(String type);
}
public interface Pizza {
void prepare(); // 피자 만들 준비
void bake(); // 피자 굽기
void cut(); // 피자 커팅
void box(); // 다 만든 피자 박스에 담기
}
public CheesePizza implements Pizza { ... }
public GreekPizza implements Pizza { ... }
public PepperoniPizza implements Pizza { ... }
즉, 객체 생성을 서브 클래스에 위임한다는 의미인데요,
이제 PizzaStore를 상속받는 구상(Concrete) PizzaStore 클래스를 살펴보겠습니다.
public class NYPizzaStore extends PizzaStore {
public Pizza createPizza(String type) {
Pizza pizza = null;
if ("cheese".equals(type)) {
pizza = new CheesePizza();
} else if ("pepperoni".equals(type)) {
pizza = new PepperoniPizza();
}
return pizza;
}
}
3. 추상 팩토리 패턴
추상 팩토리는 처음에 살펴봤던 팩토리를 추상화한거라고 이해하면 됩니다.
팩토리 메서드가 완전한 하나의 제품을 생성하기 위한 용도라면, 추상 팩토리는 제품군(일련의 재료들)을 생성하기 위한 용도입니다.
public class NYPizzaStore extends PizzaStore {
// 피자에는 빵, 도우, 치즈, 소스 등 여러가지 재료들이 있을 겁니다.
// 어떤 스타일의 재료들을 사용할지를 정해야 할텐데, 이때 아래의 추상 팩토리가 사용됩니다.
ProductFactory factory = NYProductFactory();
public Pizza createPizza(String type) {
Pizza pizza = null;
if ("cheese".equals(type)) {
// Concrete Pizza 객체를 생성하면서 추상 팩토리를 넘깁니다.
pizza = new CheesePizza(factory);
} else if ("pepperoni".equals(type)) {
pizza = new PepperoniPizza(factory);
}
return pizza;
}
}
'Design Pattern' 카테고리의 다른 글
[Design Pattern] 커맨드 패턴 (0) | 2020.02.14 |
---|---|
[Design Pattern] 어탭터 패턴과 퍼사드 패턴 (0) | 2020.01.31 |
[Design Pattern] 데코레이터 패턴 (0) | 2020.01.17 |
[Design Pattern] 옵저버 패턴 (0) | 2020.01.10 |
[Design Pattern] 디자인 패턴이란? (0) | 2020.01.09 |
댓글
이 글 공유하기
다른 글
-
[Design Pattern] 커맨드 패턴
[Design Pattern] 커맨드 패턴
2020.02.14 -
[Design Pattern] 어탭터 패턴과 퍼사드 패턴
[Design Pattern] 어탭터 패턴과 퍼사드 패턴
2020.01.31 -
[Design Pattern] 데코레이터 패턴
[Design Pattern] 데코레이터 패턴
2020.01.17 -
[Design Pattern] 옵저버 패턴
[Design Pattern] 옵저버 패턴
2020.01.10