Factory Pattern
Factory Pattern μ 리 [μ± μμ μμ£Ό μΈκΈνλ λ΄μ©]
- ꡬνμ λ°νμΌλ‘ νλ‘κ·Έλλ°νλ€. β
new Object()
- λ³νλ₯Ό λ°νμΌλ‘ νλ‘κ·Έλλ°νλ€. β
GetObject()
μν©
κ°μ²΄λ₯Ό μμ±νλ λΆλΆμ΄ κ³μ λ³κ²½λ λ, μ°λ¦¬λ νΌμ ν΄λμ€λ₯Ό ν΅ν΄μ νΌμλ₯Ό μμ±ν κ²μΈλ€. νμ§λ§ νΌμμ μ’ λ₯λ λ§κ³ , νλ§€νλ νΌμλ κ³μ βλ³νλ€.β μμμλ κ°μ‘°ν μμΉμ λ³νλ λΆλΆκ³Ό λ³νμ§ μλ λΆλΆμ λΆλ¦¬νλ κ²μ΄λ€. νλ§€νλ νΌμκ° λ³κ²½λλ©΄ μλμ λ©μλλ κ³μ μμ ν΄μΌ νλ€.
1
2
3
4
5
6
7
8
9
10
11
12
Pizza orderPizza(string type){
Pizza pizza;
if(type.equals("cheese"))
pizza=new CheesePizza();
else if(type.equals("pepperoni"))
pizza=new PepperoniPizza();
else if(type.equals("clam")
pizza=new ClamPizza();
else if(type.equals("veggie"))
pizza=new VeggiePizza();
}
...
λ§μ½, νΌμκ°κ²κ° μ¬λ¬κ°λΌλ©΄, νΌμλ₯Ό μμ±νλ ν΄λμ€λ νλκ° μλ λ€μκ° λλ€. μ΄λ μ¬λ¬ ν΄λμ€λ₯Ό μμ ν΄μΌνλ€. μ΄λ° μμ‘΄μ±μ μμ κΈ° μν΄ SimpleFactory ν΄λμ€λ₯Ό λμ νλ€.(μ¦, κ°μ²΄λ₯Ό μμ±νλ λΆλΆμ ν΄λμ€λ‘ λΆλ¦¬ν¨)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class SimpleFactory{
public Pizza createPizza(String type){
Pizza pizza = null;
if(type.equals("cheese")){
pizza = new CheesePizza();
}else if(type.equals("pepperoni")){
pizza = new PepperoniPizza();
}else if(type.equals("clam")){
pizza = new ClamPizza();
}else if(type.equals("veggie")){
pizza = new VeggiePizza();
}
return pizza;
}
}
νμ§λ§ μ΄λ° SImple Factoryλ λμμΈ ν¨ν΄μ΄ μλκ³ , ꡬν μ€ν¬μ λμ΄λ€.
Factory Pattern λ?
μ¬λ¬ νμ ν΄λμ€λ₯Ό μμ±ν λ, κ° ν΄λμ€λ³λ‘ μμ‘΄μ±μ κ°κ³ μΆμ§ μμ λ μ£Όλ‘ μ¬μ©νλ ν¨ν΄μΌλ‘ κ°μ²΄ μμ±μ μ± μμ ν΄λμ€ λλ λ©μλμ μμνλ€. κ²°κ³Όμ μΌλ‘ κ°μ²΄ μμ±λ‘μ§μ΄ μ£Όμ λΉμ¦λμ€ λ‘μ§κ³Ό λΆλ¦¬λλ€.
When?
λ¬Έμ μν©: νμ ν΄λμ€λ₯Ό μμ±νλ μ½λλ₯Ό λΆλ¦¬νκ³ μΆμ λ
- ꡬ체μ μΈ μ½λ μν©μΌλ‘λ λ€λ₯Έ ν΄λμ€μμ
new instance_type
λͺ λ Ήμ΄λ₯Ό μ€ννκ³ μΆμ§ μμ λ
νμ ν΄λμ€λ₯Ό μ§μ μμ±νλ©΄, νμ ν΄λμ€κ° μΆκ°λκ±°λ, λ³κ²½, μμ λ λλ§λ€ κΈ°μ‘΄μ μ½λλ₯Ό μμ ν΄μΌ νλ μμ‘΄μ±μ΄ μκΈ΄λ€. μ΄λ₯Ό ν΄κ²°νκΈ° μν΄, ν©ν 리λΌλ ν΄λμ€λ₯Ό ν΅ν΄ λͺ¨λ μμ±μ μμνλ€.
- μ£Όλ‘, ν©ν 리 ν¨ν΄μΌλ‘ ꡬνν ν(λ§μ½ λ μ μ°ν΄μΌ νλ€λ©΄) μΆμν ν¨ν΄, νλ‘ν νμ , λΉλ ν¨ν΄μΌλ‘ μ λ°μ΄νΈνλ€.
ꡬνμ ν΅ν΄ Single Responsibility Principleμ λ§μ‘±νλ€.
Factory Method Pattern
μ μ
ν©ν 리 λ©μλ ν¨ν΄μ κ°μ²΄λ₯Ό μμ±ν λ νμν μΈν°νμ΄μ€λ₯Ό ν΄λμ€λ‘ μ μνλ€.(κ°λ¨ν ꡬμ±μ΄ μλλΌλ©΄ abstract methodλ₯Ό μ¬μ©νλ€.) μΈμ€ν΄μ€λ₯Ό λ§λλ κ²μ νμ ν΄λμ€μμ κ²°μ νλ€.
μν©
μμ μν©μμ μΈκΈνλ κ² μ²λΌ, μ μ©λλ ν΄λμ€κ° νλκ° μλκ³ , μμ±νλ λ°©μμ΄ λ€λ₯΄λ€λ©΄ μμ κ°μ λ°©λ²μΌλ‘ λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μ΄λ ΅λ€. λ§μ½ μ€κ΅, νκ΅, λ―Έκ΅ μ§μ μ΄ μλ€κ³ κ°μ νλ©΄ PizzaStoreλ Factoryλ‘ μ€κ΅ λ―Έκ΅ νκ΅ μ§μ μ λͺ¨λ κ°μ§κ³ μμ΄μΌνλ€. λΆνμν ꡬμ±μ΄λ€. κ·Έλ κΈ°μ Method Patternμ μ΄μ©νλ€.
μμ ν΄λμ€μμ μΈμ€ν΄μ€λ₯Ό μμ±νλ λΆλΆμ
abstrct method()
λ‘ μ μνλ€.1 2 3 4 5 6 7 8 9 10 11 12 13 14
public abstract class PizzaStore { protected abstract Pizza createPizza(String item); public Pizza orderPizza(String type) { Pizza pizza = createPizza(type); System.out.println("--- Making a " + pizza.getName() + " ---"); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } }
νμ ν΄λμ€μμ μ΄λ₯Ό μ€λ²λΌμ΄λ©νμ¬, μλ§μ νΌμλ₯Ό μμ±νλ€.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
public class NYPizzaStore extends PizzaStore { Pizza createPizza(String item) { if (item.equals("cheese")) { return new NYStyleCheesePizza(); } else if (item.equals("veggie")) { return new NYStyleVeggiePizza(); } else if (item.equals("clam")) { return new NYStyleClamPizza(); } else if (item.equals("pepperoni")) { return new NYStylePepperoniPizza(); } else return null; } }
μ΄λ κ²νλ©΄, λκ°μ μμ€ν
(orderPizza
λ±)λ₯Ό μ΄μ©νλ©΄μ λμ μΌλ‘ μλ§μ νΌμλ₯Ό μμ±ν μ μλ€, μΆν λ€λ₯Έ νΌμκ° μΆκ°λλ€λ©΄ ν΄λΉ νΌμν΄λμ€λ₯Ό μμ±νκ³ Factoryμ μΆκ°νλ©΄λλ€.
μμ‘΄μ± μμ
λ§μ½, ν©ν 리 ν¨ν΄μ μ¬μ©νμ§ μκ³ μ΄κΈ° μν©μ²λΌ PizzaStore ν΄λμ€μμ κ°μ²΄λ₯Ό μμ±νλ€λ©΄, μ¬λ¬ Pizza μ’ λ₯μ μμ‘΄μ±μ κ°κ²λλ€. κ° μ’ λ₯μ Pizzaλ ꡬμ±ν΄λμ€μ΄μ§λ§, Pizzaκ° λ³νλ€λ©΄ PizzaStoreμ μ½λλ λ³κ²½ν΄μΌ νλ€. μ¦, PizzaStoreλ μ¬λ¬ μ’ λ₯μ Pizzaμ μμ‘΄μ±μ κ°μ§λ€. μ¦, ꡬνμ μμ‘΄νκ² λλ€.
μμ‘΄μ± μμ μμΉμ βꡬνμ μμ‘΄νμ§ μκ³ , μΆμνλ κ²μ μμ‘΄νλ€βλΌλ μμΉμ΄λ€.
1
2
3
4
5
6
7
8
9
10
11
12
Pizza orderPizza(string type){
Pizza pizza;
if(type.equals("cheese"))
pizza=new CheesePizza();
else if(type.equals("pepperoni"))
pizza=new PepperoniPizza();
else if(type.equals("clam")
pizza=new ClamPizza();
else if(type.equals("veggie"))
pizza=new VeggiePizza();
}
...
ν©ν 리 λ©μλ ν¨ν΄μ μ μ©νλ©΄, κ° νΌμ ν΄λμ€κ° μλ PizzaλΌλ abstract classμ μμ‘΄νκ² λλ€.
μμ‘΄μ± μμ μμΉ μ§ν€λ λ²
- λ³μμ ꡬμ ν΄λμ€μ λ νΌλ°μ€λ₯Ό μ μ₯νμ§ μλλ€.(new μ°μ°μ)
- ꡬμ ν΄λμ€μμ μ λλ ν΄λμ€λ₯Ό λ§λ€μ§ μλλ€.
- λ² μ΄μ€ ν΄λμ€μ μ΄λ―Έ ꡬνλμ΄ μλ λ©μλλ₯Ό μ€λ²λΌμ΄λνμ§ μλλ€. (λ² μ΄μ€ ν΄λμ€κ° μ λλ‘λ μΆμνλμ§ μκΈ°μ)
μμ μμΉμ μ§ν€λ Java νλ‘κ·Έλ¨μ κ±°μ μλ€. λ€λ§, μμΌλ‘ μ§μμ μΈ λ³νκ° νμνλ€λ©΄ ν¨ν΄μ μ€μν΄μΌ μ μ§λ³΄μμ νΈνλ€.
λ¨μ
ν©ν 리 λ©μλλ₯Ό μ΄μ©νλ©΄ νμ μμ μ±(type - safety)μ μ§μ₯μ΄ μμ μ μλ€. μμ μμμλ string μ λ ₯λλ μΈμκ° μλͺ»μ λ¬λλ©΄ nullμ λ°ννκ² λλ€.
- μμ ν΄κ²°λ°©λ²μΌλ‘λ νμμ κ³ μ νλ€. μ μ μμ νΉμ enum, λ§€κ°λ³μλ₯Ό λνλ΄λ νΉλ³ν κ°μ²΄λ₯Ό ν΅ν΄ ν΄κ²°ν μ μλ€.
μΆμ ν©ν 리 ν¨ν΄
μΆμ ν©ν 리 ν¨ν΄μ ꡬμ ν΄λμ€μ μμ‘΄νμ§ μκ³ λ μλ‘ μ°κ΄λκ±°λ μμ‘΄μ μΈ κ°μ²΄λ‘ μ΄λ£¨μ΄μ§ μ νκ΅°μ μμ±νλ μΈν°νμ΄μ€λ₯Ό μ 곡νλ€. μΌλ ¨λ μ΄λΌλ λ§μμ, ν©ν 리 λ©μλμ λ€λ₯΄λ€. ν©ν 리 λ©μλλ νλμ μΈμ€ν΄μ€λ§ μμ±νλ λ°λ©΄, μΆμ ν©ν 리 ν¨ν΄μΌλ‘λ μΌλ ¨λ(μ°κ΄λ)μΈμ€ν΄μ€λ₯Ό λͺ¨λ μμ±ν μ μλ€.
μν©
μμ νΌμλ₯Ό μ μνμ λ, μ΄μ κ° μ§μ λ§λ€ μ¬λ£λ₯Ό λ¬λ¦¬ μ¬μ©νλ€κ³ νλ€. μ’ λ₯λ μλμ κ°μ΄ μ΄ 6κ°κ° μλ€.
1
2
3
4
5
6
Dough dough;
Sauce sauce;
Veggies veggies[];
Cheese cheese;
Pepperoni pepperoni;
Clams clam;
μ΄λ΄ κ²½μ°, κ° μ§μ μμ νΌμλ₯Ό μμ±ν λ ν©ν 리λ₯Ό μ΄μ©νμ¬ μ¬λ£λ₯Ό μ€μ ν΄μ€μΌνλ€.
μλλ λ΄μ νΌμ μ¬λ£ ν©ν 리μ΄λ€.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class NYPizzaIngredientFactory implements PizzaIngredientFactory {
public Dough createDough() {
return new ThinCrustDough();
}
public Sauce createSauce() {
return new MarinaraSauce();
}
public Cheese createCheese() {
return new ReggianoCheese();
}
public Veggies[] createVeggies() {
Veggies veggies[] = { new Garlic(), new Onion(), new Mushroom(), new RedPepper() };
return veggies;
}
public Pepperoni createPepperoni() {
return new SlicedPepperoni();
}
public Clams createClam() {
return new FreshClams();
}
}
μ΄μ νΌμ μμ±κ³Όμ μ μ²μ²ν μ΄ν΄λ³΄λ©΄
- λ΄μ νΌμ κ°κ²μμ μΉμ¦ νΌμλ₯Ό μ£Όλ¬Ένλ€.
NYPizzaStore.orderPizza(βcheeseβ);
- orderPizza λ§€μλ λ΄λΆμμ createPizza(βcheeseβ)λ₯Ό νΈμΆνλ€.
μ²μμ μ§μ λ μμ¬λ£ ν©ν 리λ₯Ό ν΅ν΄, μΉμ¦νΌμκ° μμ±λλ€.
1
Pizza pizza = new CheesePizza(ingredientFactory);
- cheese νΌμ ν΄λμ€ μΌλΆ
1 2 3 4 5 6
void prepare() { System.out.println("Preparing " + name); dough = ingredientFactory.createDough(); sauce = ingredientFactory.createSauce(); cheese = ingredientFactory.createCheese(); }
λ¨μ
μλ‘μ΄ μ νμ μΆκ°νκ±°λ, μλ‘μ΄ λν μΆκ°μ κ°μ΄ λ΄λΆλ₯Ό λ³κ²½νλ©΄ μΈν°νμ΄μ€λ₯Ό μ λ©΄ μμ ν΄μΌ νλ€. μ¦, μλΈ ν΄λμ€μ μΈν°νμ΄μ€λ μ λΆ μμ ν΄μΌ νλ€. κ·Έλ κΈ°μ μλ‘μ΄ μμκ° μ μΆκ°λμ§ μκ³ , λ§λλ λ°©μμ΄ μ¬λ¬κ° νμν κ²½μ° μ μ©νλ€. μ¦, λ³νμ μμκ° μ¬λ£κ° μλ νΌμμΈ κ²½μ° μ μ©νλ€.
ν©ν 리 λ©μλ vs μΆμ ν©ν 리
μ¬μ©λ°©μ
- μμ λ° μ€λ²λΌμ΄λ©, μ¦ μλΈ(νμ) ν΄λμ€μμ μμ±μ λ΄λΉ
- κ°μ²΄ ꡬμ±(factoryλ₯Ό λ©€λ²λ³μλ‘), ν©ν 리μμ μμ±μ λ΄λΉ