# Factory Pattern (1) Factory Method Pattern
Assembled by GimunLee
# Goal
- Factory Patternμ κ°λ μ μ μ μλ€.
- Simple Factoryμ Factory Method Patternμ μ°¨μ΄μ μ λν΄ μ€λͺ ν μ μλ€.
- Factory Method Patternμ μ¬μ© μ΄μ μ λν΄ μ€λͺ ν μ μλ€.
# νΌμ κ°κ² 차리기
μ¬λ¬λΆμ΄ νΌμ κ°κ²λ₯Ό μ΄μνκ³ μκ³ , κ°μ²΄λ§μμ μ΅μ²¨λ¨ νΌμ κ°κ² μ£ΌμΈλ΅κ² λ€μκ³Ό κ°μ μ½λλ₯Ό λ§λ€μλ€κ³ κ°μ ν΄ λ΄ μλ€.
Pizza orderPizza(String type) { // νΌμ μ’
λ₯ μ λ¬
Pizza pizza;
if(type.equals("cheese")){
pizza = new CheesePizza();
}else if(type.equals("greek")){
pizza = new GreekPizza();
}else if(type.equals("pepperoni")){
pizza = new PepperoniPizza();
}
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
νΌμ κ°κ²μμ μ‘°κ° νΌμ(Clam Pizza)νκ³ μΌμ± νΌμ(Veggie Pizza)λ₯Ό λ©λ΄μ μΆκ°νκΈ°λ‘ νμ΅λλ€. κ·Έλ¦¬κ³ κ·Έλ¦¬μ€μ(Greek Pizza)κ° λ³λ‘ μ νλ €μ λ©λ΄μμ μ μΈμν€κΈ°λ‘ νμ΅λλ€.
Pizza orderPizza(String type) { // νΌμ μ’
λ₯ μ λ¬
Pizza pizza;
if(type.equals("cheese")){
pizza = new CheesePizza();
}
// else if(type.equals("greek")){
// pizza = new GreekPizza();
// }
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.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
orderPizza() λ©μλμμ κ°μ₯ λ¬Έμ κ° λλ λΆλΆμ λ°λ‘ μΈμ€ν΄μ€λ₯Ό λ§λ€ ꡬμ ν΄λμ€λ₯Ό μ ννλ λΆλΆμ λλ€. κ·Έ λΆλΆ λλ¬Έμ μν©μ λ°λΌ μ½λλ₯Ό λ³κ²½ν μ λ°μ μμ΅λλ€. μ΄μ μ΄λ€ λΆλΆμ΄ λ°λκ³ μ΄λ€ λΆλΆμ΄ λ°λμ§ μλμ§λ₯Ό νμ νμΌλ μΊ‘μνλ₯Ό ν΄λ³΄κ² μ΅λλ€.
# κ°μ²΄ μμ± μΊ‘μν
κ°μ²΄ μμ± μ½λλ§ λ°λ‘ λΉΌμ νΌμ κ°μ²΄λ₯Ό λ§λλ μΌλ§ μ λ΄νλ λ€λ₯Έ κ°μ²΄μ μ§μ΄λ£μ΄ 보λλ‘ νκ² μ΅λλ€.
μλ‘ λ§λ€ κ°μ²΄μλ ν©ν 리(FactoryλΌλ μ΄λ¦μ λΆμ΄κΈ°λ‘ ν©μλ€.
κ°μ²΄ μμ±μ μ²λ¦¬νλ ν΄λμ€λ₯Ό ν©ν 리λΌκ³ λΆλ¦ λλ€. μΌλ¨ SimplePizzaFactoryλ₯Ό λ§λ€κ³ λλ©΄ orderPizza() λ©μλλ μλ‘ λ§λ κ°μ²΄μ ν΄λΌμ΄μΈνΈκ° λ©λλ€. μ¦ μλ‘ λ§λ κ°μ²΄λ₯Ό νΈμΆνλ κ±°μ£ . νΌμκ° νμν λ λ§λ€ νΌμ 곡μ₯μ νΌμ νλ λ§λ€μ΄ λ¬λΌκ³ λΆννλ€κ³ μκ°νλ©΄ λ©λλ€. μ΄μ λ μ΄μ orderPizza() λ©μλμμ μ΄λ€ νΌμλ₯Ό λ§λ€μ΄μΌ νλμ§ κ³ λ―Όνμ§ μμλ λ©λλ€. orderPizza() λ©μλμμλ Pizza μΈν°νμ΄μ€λ₯Ό ꡬννλ νΌμλ₯Ό λ°μμ κ·Έ μΈν°νμ΄μ€μμ μ μνλ prepare(), bake(), cut(), box() λ©μλλ₯Ό νΈμΆνκΈ°λ§ νλ©΄ λ©λλ€.
# κ°λ¨ν νΌμ ν©ν 리 λ§λ€κΈ°
μλ‘ λ§λ€ SimplePizzaFactory ν΄λμ€μμ νλ μΌμ νλ λΏμ λλ€. ν΄λΌμ΄μΈνΈλ₯Ό μν΄μ νΌμλ₯Ό λ§λ€μ΄μ£ΌκΈ°λ§ νλ©΄ λ©λλ€.
public class SimplePizzaFactory {
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();
}
}
# λ°λ³΄κ°μ μ§λ¬Έμ μμ΅λλ€.
# μ΄λ κ² νλ©΄ λ¬΄μ¨ μ₯μ μ΄ μλ 건κ°μ? μκΉ κ·Έ λ¬Έμ λ₯Ό κ·Έλ₯ λ€λ₯Έ κ°μ²΄λ‘ λ겨 λ²λ Έμ λΏμΈ κ² κ°μλ°μ?
SimplePizzaFactoryλ₯Ό μ¬μ©νλ ν΄λΌμ΄μΈνΈκ° λ§€μ° λ§μ μ μλ€λ μ μ μκ°ν΄ 보μΈμ. μ¬κΈ°μλ orderPizza() λ©μλλ§ λμ μμ§λ§, νΌμ κ°μ²΄λ₯Ό λ°μμ κ°κ²©μ΄λΌλ κ° νΌμμ λν μ€λͺ λ±μ μ°Ύμμ νμ©νλ PizzaShopMenu κ°μ ν΄λμ€λΌλ κ°, μκΉ λ΄€λ PizzaStore ν΄λμ€μμ νλ κ²κ³Όλ μ‘°κΈ λ€λ₯Έ λ°©μμΌλ‘ νΌμ μ£Όλ¬Έμ μ²λ¦¬νλ HomeDelivery κ°μ ν΄λμ€μμλ μ΄ ν©ν 리λ₯Ό μ¬μ©ν μ μμ κ²μ λλ€.
# λΉμ·ν μμ ν©ν 리λ₯Ό μ°λλ°, λ©μλλ₯Ό μ μ λ©μλλ‘ μ μΈν λμμΈμ λ³Έ μ μ΄ μμ΄μ. κ·Έ λμμΈμ΄λ μ΄ λμμΈμ μ΄λ»κ² λ€λ₯Έκ±°μ£ ?
κ°λ¨ν ν©ν 리λ₯Ό μ μ λ©μλλ‘ μ μνλ κΈ°λ²λ μΌλ°μ μΌλ‘ λ§μ΄ μ°μ λλ€. μ μ ν©ν 리(static factory)λΌκ³ λΆλ₯΄κΈ°λ νμ£ . μ μ μ λ©μλλ₯Ό μ°λμ§ κΆκΈνμ£ ? μ μ λ©μλλ₯Ό μ°λ©΄ κ°μ²΄λ₯Ό μμ±νκΈ° μν λ©μλλ₯Ό μ€νμν€κΈ° μν΄μ κ°μ²΄μ μΈμ€ν΄μ€λ₯Ό λ§λ€μ§ μμλ λκΈ° λλ¬Έμ λλ€. νμ§λ§ μλΈν΄λμ€λ₯Ό λ§λ€μ΄μ κ°μ²΄ μμ± λ©μλμ νλμ λ³κ²½μν¬ μ μλ€λ λ¨μ μ΄ μλ€λ κ²λ κΌ κΈ°μ΅ν΄λμΈμ.
μ΄μ ν΄λΌμ΄μΈνΈ μ½λλ₯Ό κ³ μ³λ³΄κ² μ΅λλ€.
public class PizzaStore {
SimplePizzaFactory factory;
public PizzaStore (SimplePizzaFactory factory) {
this.factory = factory;
}
public Pizza orderPizza(String type){
Pizza pizza;
pizza = factory.createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
κ°λ¨ν ν©ν 리(Simple Factory)λ λμμΈ ν¨ν΄μ΄λΌκ³ ν μλ μμ΅λλ€. νλ‘κ·Έλλ°μ νλλ° μμ΄μ μμ£Ό μ°μ΄λ κ΄μ©κ΅¬μ κ°κΉλ€κ³ ν μ μμ΅λλ€.
μμμ λ§λ νΌμ κ°κ² νλ‘κ·Έλ¨μ ν΄λμ€ λ€μ΄μ΄κ·Έλ¨μ νλ² μ΄ν΄λ³΄κ² μ΅λλ€.
κ°λ¨ν ν©ν 리λ μλ°μ μ΄λΌκ³ μκ°ν©μλ€. μ΄μ λΆν° ν©ν 리μ ν΄λΉνλ λ κ°μ§ κ°λ ₯ν ν¨ν΄μ μμλ³΄κ² μ΅λλ€.
# νΌμ νλ μ°¨μ΄μ¦ μ¬μ
νλ μ°¨μ΄μ¦λ₯Ό μ΄μνκ² λμ΅λλ€. μ§κΈκΉμ§ μ μ¨μλ μ½λλ₯Ό λ€λ₯Έ μ§μ μμλ μΈ μ μλλ‘ λ§λ€κΈ°λ‘ νμ΅λλ€.
νμ§λ§ μ§μλ³λ‘ μ‘°κΈμ© λ€λ₯Έ μ°¨μ΄μ μ μ΄λ€ μμΌλ‘ μ μ©ν΄μΌ ν κΉμ? κ° μ§μ λ§λ€ κ·Έ μ§μμ νΉμ±κ³Ό μ λ§μ λ°μνμ¬ λ€λ₯Έ μ€νμΌμ νΌμ(λ΄μ₯ μ€νμΌ, μμΉ΄κ³ μ€νμΌ, μΊλ¦¬ν¬λμ μ€νμΌ)λ₯Ό λ§λ€μ΄μΌ ν©λλ€.
SimplePizzaFactoryλ₯Ό λΉΌκ³ μΈ κ°μ§ μλ‘ λ€λ₯Έ ν©ν 리(NYPizzaFactory, ChicagoPizzaFactory, CaliforniaPizzaFactory)λ₯Ό λ§λ λ€μ, PizzaStoreμμ μ λΉν ν©ν 리λ₯Ό μ¬μ©νλλ‘ νλ©΄ λΆμ μμλ μ ν λ¬Έμ μμ΄ μΈ μ μμ κ²μ λλ€.
κ·Έ λ°©λ²μ μ μ©νλ©΄ μ΄λ»κ² λ μ§ νλ² μ΄ν΄λ³΄κ² μ΅λλ€.
λ΄μ₯ λΆμ
NYPizzaFactory nyFactory = new NYPizzaFactory();
PizzaStore nyStore = new PizzaStore(nyFactory);
nyStore.order("Veggie");
μμΉ΄κ³ λΆμ
ChicagoPizzaFactory chicagoFactory = new ChicagoPizzaFactory();
PizzaStore chicagoStore = new PizzaStore(chicagoFactory);
chicagoStore.order("Veggie");
λ°©κΈ μκΈ°ν λ°©λ²μ μ§μ μ μ©ν΄ λ΄€μ΅λλ€. νμ§λ§, λ³Έμ μμ μ°λ¦¬κ° λ§λ ν©ν 리λ₯Ό μ¨μ νΌμλ₯Ό λ§λ€κΈ΄ νλλ°, λ μμ μΈ λ°©λ²λ€μ μ¬μ©νκΈ° μμνμ΅λλ€. κ΅½λ λ°©μμ΄ λ¬λΌμ§λ€κ±°λ μ’ μ’ νΌμλ₯Ό μλ₯΄λ κ²μ κΉλ¨Ήμ΄ λ²λ¦¬λ μΌμ΄ μΌμ΄λκΈ° μμνμ΅λλ€.
μ΄ λ¬Έμ λ₯Ό λ€μ νλ² μκ°ν΄λ³΄λ, νΌμ κ°κ²μ νΌμ μ μ κ³Όμ μ 체λ₯Ό νλλ‘ λ¬Άμ΄μ£Όλ νλ μμν¬λ₯Ό λ§λ€μ΄μΌ λκ² λ€λ κ²°λ‘ μ λλ¬νμ΅λλ€. λ¬Όλ‘ κ·Έλ κ² νλ©΄μλ μ μ°μ±μ μμ΄λ²λ¦¬λ©΄ μ λκ² μ£ .
SimplePizzaFactoryλ₯Ό λ§λ€κΈ° μ μ μΌλ μ½λμμλ νΌμλ₯Ό λ§λλ μ½λκ° PizzaStoreνκ³ μ§μ μ°κ²°λμ΄ μκΈ΄ νμμ§λ§, μ μ°μ±μ΄ μ ν μμμ΅λλ€.
κ·Έλ¬λ©΄ μ΄λ»κ² ν΄μΌ νΌμ κ°κ²νκ³ νΌμ λ§λλ κ³Όμ μ νλλ‘ λ¬Άμ μ μμκΉμ?
# νΌμ κ°κ² νλ μμν¬
νΌμλ₯Ό λ§λλ ν λ μ체λ μ λΆ PizzaStore ν΄λμ€μ κ΅νμν€λ©΄μλ λΆμ λ§λ€ κ³ μ μ μ€νμΌμ μ΄λ¦΄ μ μλλ‘ νλ λ°©λ²μ΄ μμ΅λλ€.
μ΄μ createPizza() λ©μλλ₯Ό PizzaStoreμ λ€μ μ§μ΄λ£κ² μ΅λλ€. νμ§λ§ μ΄λ²μλ κ·Έ λ©μλλ₯Ό μΆμ λ©μλ λ‘ μ μΈνκ³ , κ° μ§μλ§λ€ κ³ μ μ μ€νμΌμ λ§κ² PizzaStoreμ μλΈν΄λμ€λ₯Ό λ§λ€λλ‘ ν κ²μ λλ€.
μ°μ PizzaStoreκ° μ΄λ»κ² λ¬λΌμ§λμ§ μ΄ν΄λ³΄κ² μ΅λλ€.
public abstract class PizzaStore {
public Pizza orderPizza(String type){
Pizza pizza;
pizza = createPizza(type); // ν©ν 리 κ°μ²΄κ° μλ PizzaStoreμ μλ λ©μλ νΈμΆ
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
abstract Pizza createPizza(String type); // ν©ν 리 κ°μ²΄ λμ μ΄ λ©μλ μ¬μ©
}
κ° λΆμ μ μν μλΈν΄λμ€κ° νμν©λλ€. μ΄μ κ° μ§μλ³λ‘ μλΈν΄λμ€λ₯Ό λ§λ€μ΄μΌ ν©λλ€. νΌμμ μ€νμΌμ κ° μλΈν΄λμ€μμ κ²°μ ν©λλ€. μ΄λ€ μμΌλ‘ λμκ°λμ§ μ΄ν΄λ΄ μλ€.
# μλΈν΄λμ€μμ κ²°μ λλ κ²
PizzaStoreμ orderPizza() λ©μλμ μ΄λ―Έ μ£Όλ¬Έ μμ€ν μ΄ μ κ°μΆ°μ Έ μμ΅λλ€. μ΄ μ£Όλ¬Έ μμ€ν μ체λ λͺ¨λ λΆμ μμ λκ°μ΄ μ§νλμ΄μΌ ν©λλ€.
κ° λΆμ λ§λ€ λ¬λΌμ§ μ μλ κ²μ νΌμμ μ€νμΌ λΏμ λλ€. λ΄μ₯ν νΌμλ λΉ΅μ΄ μκ³ , μμΉ΄κ³ ν νΌμλ λΉ΅μ΄ λκΊΌμ΄ μμΌλ‘ λ§μ΄μ£ . μ΄λ κ² λ¬λΌμ§λ μ λ€μ createPizza() λ©μλμ μ§μ΄λ£κ³ κ·Έ λ©μλμμ ν΄λΉ μ€νμΌμ νΌμλ₯Ό λ§λλ κ²μ λͺ¨λ μ± μμ§λλ‘ ν κ³νμ λλ€. PizzaStoreμ μλΈν΄λμ€μμ createPizza() λ©μλλ₯Ό ꡬννλλ‘ νλ©΄ λμ£ . μ΄μ PizzaStore νλ μμν¬μ μΆ©μ€νλ©΄μλ κ°κ°μ μ€νμΌμ μ λλ‘ κ΅¬νν μ μλ orderPizza() λ©μλλ₯Ό κ°μ§κ³ μλ PizzaStore μλΈν΄λμ€λ€μ ꡬλΉν μ μμ΅λλ€.
λ΄μ₯ λΆμ
public class NYPizzaStore extends PizzaStore {
// μΆμλ©μλλ‘ μ μΈλμκΈ° λλ¬Έμ λ°λμ ꡬν
public Pizza createPizza(String item) {
if(item.equals("cheese")){
return new NYStyleCheesePize();
}else if(item.equals("pepperoni")){
return new NYStylePepperoniPizza();
}else if(item.equals("clam")){
return new NYStyleClamPizza();
}else if(item.equals("veggie")){
return new NYStyleVeggiePizza();
}else{
return null;
}
}
}
μνΌν΄λμ€μ μλ orderPizza() λ©μλμμλ μ΄λ€ νΌμκ° λ§λ€μ΄μ§λμ§ μ ν μ μ μλ€λ μ μ μ μ΄ν΄ν΄μΌν©λλ€. κ·Έ λ©μλμμλ νΌμλ₯Ό μ€λΉνκ³ κ΅½κ³ μλ₯΄κ³ ν¬μ₯νλ μμ μ μ²λ¦¬ν λΏμ λλ€.
# ν©ν 리 λ©μλ μ μΈ
PizzaStoreλ₯Ό λͺ κ΅°λ° κ³ μΉ κ²°κ³Ό,
ꡬμ ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό λ§λλ μΌμ ν κ°μ²΄μμ μ λΆ μ²λ¦¬νλ λ°©μ μμ
μΌλ ¨μ μλΈν΄λμ€μμ μ²λ¦¬νλ λ°©μ μΌλ‘ λμ΄μ€κ² λμμ΅λλ€. νλ² μμΈν μ΄ν΄λ³΄κ² μ΅λλ€.
public abstract class PizzaStore {
public Pizza orederPizza(String type){
Pizza pizza;
pizza = createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
// Pizza μΈμ€ν΄μ€λ₯Ό λ§λλ μΌμ μ΄μ ν©ν 리 μν μ νλ λ©μλμμ 맑μμ μ²λ¦¬
protected abstract Pizza createPizza(String type);
}
ν©ν 리 λ©μλλ κ°μ²΄ μμ±μ μ²λ¦¬νλ©°, ν©ν 리 λ©μλλ₯Ό μ΄μ©νλ©΄ κ°μ²΄λ₯Ό μμ±νλ μμ μ μλΈν΄λμ€μμ μΊ‘μνμν¬ μ μμ΅λλ€. μ΄λ κ² νλ©΄ μνΌν΄λμ€μ μλ ν΄λΌμ΄μΈνΈ μ½λμ μλΈν΄λμ€μ μλ κ°μ²΄ μμ± μ½λλ₯Ό λΆλ¦¬μν¬ μ μμ΅λλ€.
abstract Product factoryMethod(String type)
# νΌμ μ£Όλ¬Έ
@μλ¨ : λλ λ΄μ₯ν νΌμκ° μ’μ. μκ³ λ°μλ°μν λΉ΅μ μΉμ¦λ μ½κ°λ§ μ¬λ¦¬κ³ , λ§μλ μμ€λ₯Ό μ¨μΌ μ§μ§ νΌμ λ§μ΄ λμ§.
νΌμ ν©ν 리 λ©μλλ₯Ό μ΄μ©ν νΌμ μ£Όλ¬Έ κ³Όμ μ νλ² μ΄ν΄λ³΄κ² μ΅λλ€.
μλ¨μ΄ μ£Όλ¬Έν λ΄μμ λ°λΌκ° λ΄ μλ€. μ°μ NYPizzaStoreκ° νμν©λλ€.
PizzaStore nyPizzaStore = new NYPizzaStore();
νΌμ κ°κ²κ° ν보λμΌλκΉ μ£Όλ¬Έμ λ°μ μ μμ΅λλ€.
nyPizzaStore.orderPizza("cheese");
orderPizza() λ©μλμμ createPizza() λ©μλλ₯Ό νΈμΆν©λλ€.
Pizza pizza = createPizza("cheese");
μμ§ μ€λΉκ° λμ§ μμ νΌμλ₯Ό λ°μμ΅λλ€. μ΄μ νΌμ λ§λλ μμ μ λ§λ¬΄λ¦¬ν΄μΌ λκ² μ£ .
pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box();
mainμμλ μ΄λ»κ² μμ±ν΄μΌνλμ§ μ΄ν΄λ³΄κ² μ΅λλ€.
public class PizzaTestDrive{
public static void main(String[] args){
PizzaStore nyStore = new NYPizzaStore();
Pizza pizza = nyStore.orederPizza("cheese");
}
}
# ν©ν 리 λ©μλ ν¨ν΄
λͺ¨λ ν©ν 리 ν¨ν΄μμλ κ°μ²΄ μμ±μ μΊ‘μνν©λλ€. ν©ν 리 λ©μλ ν¨ν΄(Factory Method Pattern)μμλ μλΈν΄λμ€μμ μ΄λ€ ν΄λμ€λ₯Ό λ§λ€μ§λ₯Ό κ²°μ νκ² ν¨μΌλ‘μ¨ κ°μ²΄ μμ±μ μΊ‘μνν©λλ€. ν΄λμ€ λ€μ΄μ΄κ·Έλ¨μ μ΄ν΄λ³΄λ©΄μ μ΄ ν¨ν΄μ λ±μ₯νλ ν΄λμ€λ€μ μ΄ν΄λ³΄κ² μ΅λλ€.
# ν©ν 리 λ©μλ ν¨ν΄ μ μ
ν©ν 리 λ©μλ ν¨ν΄μμλ κ°μ²΄λ₯Ό μμ±νκΈ° μν μΈν°νμ΄μ€λ₯Ό μ μνλλ°, μ΄λ€ ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό λ§λ€μ§λ μλΈμ€ν΄λμ€μμ κ²°μ νκ² λ§λλλ€. ν©ν 리 λ©μλ ν¨ν΄μ μ΄μ©νλ©΄ ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό λ§λλ μΌμ μλΈν΄λμ€μκ² λ§‘κΈ°λ κ²μ λλ€.
ν΄λμ€ λ€μ΄μ΄κ·Έλ¨μ 보면, Creator μΆμ ν΄λμ€μμ κ°μ²΄λ₯Ό λ§λ€κΈ° μν λ©μλ, μ¦ ν©ν 리 λ©μλλ₯Ό μν μΈν°νμ΄μ€λ₯Ό μ 곡νλ€λ κ²μ μ μ μμ΅λλ€. Creator μΆμ ν΄λμ€μ ꡬνλμ΄ μλ λ€λ₯Έ λ©μλμμλ ν©ν 리 λ©μλμ μν΄ μμ°λ μ νμ κ°μ§κ³ νμν μμ μ μ²λ¦¬ν©λλ€. νμ§λ§ μ€μ ν©ν 리 λ©μλλ₯Ό ꡬννκ³ μ ν(κ°μ²΄ μΈμ€ν΄μ€)μ λ§λ€μ΄λ΄λ μΌμ μλΈν΄λμ€μμλ§ ν μ μμ΅λλ€.
μμ μλ μ μμλ λμ μμ§λ§, "κ²°μ νλ€" λΌλ ννμ μ°λ μ΄μ λ μ΄ ν¨ν΄μ μ¬μ©ν λ μλΈν΄λμ€μμ μ€νμ€μ μ΄λ€ ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό λ§λ€μ§λ₯Ό κ²°μ νκΈ° λλ¬Έμ΄ μλλΌ, μμ°μ(Creator) ν΄λμ€ μμ²΄κ° μ€μ μμ°λ μ νμ λν μ¬μ μ§μμ΄ μ ν μμ΄ λ§λ€μ΄μ§κΈ° λλ¬Έμ λλ€. μ¬μ€ λ μ ννκ² νννμλ©΄, μ¬μ©νλ μλΈν΄λμ€μ λ°λΌ μμ°λλ κ°μ²΄ μΈμ€ν΄μ€κ° κ²°μ λ κ²μ λλ€.
# λ°λ³΄κ°μ μ§λ¬Έμ μμ΅λλ€.
# 맀κ°λ³μ ν©ν 리 λ©μλλ₯Ό μ¬μ©νλ©΄ νμ μμ μ±(type-safety)μ μ§μ₯μ΄ μμ§ μλμ? κ·Έλ₯ Stringμ 맀κ°λ³μλ‘ μ λ¬ν λΏμ΄μμμ. "clam"μ μλͺ» μ³μ "calm"μ΄λΌκ³ μΉλ©΄ μ΄λ»κ² λλ κ±°μ£ ?
λ§μ½ κ·Έλ° μ€μλ₯Ό νκ² λλ©΄ μμ "λ°νμ μ€λ₯" λΌλ κ² λ°μνκ² λ©λλ€. 맀κ°λ³μ ν©ν 리 λ©μλλ₯Ό μ¬μ©ν λ νμ μμ μ±μ μ‘°κΈ λ μ 보μ₯ν΄μ€ μ μλ κΈ°λ²λ€μ΄ μκΈ΄ ν©λλ€. κ·Έλ° κΈ°λ²μ μ¬μ©νλ©΄ μλ±ν νμμ λ§λ€μ΄λΌ μ μλ μ€λ₯λ₯Ό μ»΄νμΌμμ μ‘μλΌ μ μμ£ . μλ₯Ό λ€μ΄ 맀κ°λ³μ νμμ λνλ΄κΈ° μν κ°μ²΄λ₯Ό λ§λ€ μλ μκ³ , μ μ μμλ₯Ό μΈ μλ μκ³ , μλ° 5λΆν°λ enumμ μ¬μ©ν μλ μμ΅λλ€.
# κ°λ¨ν ν©ν 리(Simple Factory)μ ν©ν 리 λ©μλμ μ°¨μ΄μ μ μμ§ μ λͺ¨λ₯΄κ² μ΄μ. ν©ν 리 λ©μλ ν¨ν΄μμλ νΌμλ₯Ό 리ν΄νλ ν΄λμ€κ° μλΈν΄λμ€λΌλ μ μ μ μΈνλ©΄ κ±°μ λκ°μμμ. μ‘°κΈ λ μμΈν μ€λͺ ν΄ μ£Όμ€ μ μλμ?
ν©ν 리 λ©μλ ν¨ν΄μ΄ κ°λ¨ν ν©ν 리μ μλΉν λΉμ·νλ€λ μ§μ μ λ§μ΅λλ€. νμ§λ§ κ°λ¨ν ν©ν 리λ μΌνμ© μ²λ°©μ λΆκ³Όν λ°λ©΄, ν©ν 리 λ©μλ ν¨ν΄μ μ΄μ©νλ©΄ μ΄λ€ ꡬνμ ν μ§λ₯Ό μλΈν΄λμ€μμ κ²°μ νλ νλ μμν¬λ₯Ό λ§λ€ μ μλ€λ κ²°μ μ μΈ μ°¨μ΄μ μ΄ μμ§μ. μλ₯Ό λ€μ΄, ν©ν 리 λ©μλ ν¨ν΄μμ μ¬μ©ν orderPizza() λ©μλμμλ νΌμλ₯Ό λ§λ€κΈ° μν μΌλ°μ μΈ νλ μμν¬λ₯Ό μ 곡ν©λλ€. κ·Έ νλ μμν¬μμλ ν©ν 리 λ©μλλ₯Ό μ΄μ©νμ¬ νΌμλ₯Ό λ§λλ ꡬμ ν΄λμ€λ₯Ό λ§λ€μμ£ . PizzaStore ν΄λμ€μ μλΈν΄λμ€λ₯Ό λ§λ€ λ, μ΄λ€ ꡬμ μ ν ν΄λμ€μμ orderPizza()μμ 리ν΄ν νΌμλ₯Ό λ§λ€μ§λ₯Ό κ²°μ νκ² λ©λλ€. μ΄ νλ μμν¬λ₯Ό κ°λ¨ν ν©ν 리νκ³ νλ² λΉκ΅ν΄ 보μΈμ. κ°λ¨ν ν©ν 리μμλ κ°μ²΄ μμ±μ μΊ‘μννλ λ°©λ²μ μ¬μ©νκΈ΄ νμ§λ§ ν©ν 리 λ©μλ ν¨ν΄μ²λΌ κ°λ ₯ν μ μ°μ±μ μ 곡νμ§ λͺ»ν©λλ€. μμ±νλ μ νμ λ§μλλ‘ λ³κ²½ν μ μκΈ° λλ¬Έμ΄μ£ .
# μμ‘΄μ± λ€μ§κΈ° μμΉ(Dependency Inversion Principle)
ꡬμ ν΄λμ€μ λν μμ‘΄μ±μ μ€μ΄λ κ²μ΄ μ’λ€λ κ²μ μ΄μ νμ€ν μ΄ν΄ν μ μμ κ²μ λλ€. μ΄λ° λ΄μ©μ μ λ¦¬ν΄ λμ κ°μ²΄μ§ν₯ λμμΈ μμΉμ΄ λ°λ‘ μμ‘΄μ± λ€μ§κΈ° μμΉ(Dependecny Inversion Principle) μ λλ€. μ΄ μμΉμ λ€μκ³Ό κ°μ μμΌλ‘ μΌλ°νμν¬ μ μμ΅λλ€.
λμμΈ μμΉ - μΆμνλ κ²μ μμ‘΄νλλ‘ λ§λ€μ΄λΌ. ꡬμ ν΄λμ€μ μμ‘΄νλλ‘ λ§λ€μ§ μλλ‘ νλ€.
μ΄ μμΉμμλ κ³ μμ€ κ΅¬μ±μμκ° μ μμ€ κ΅¬μ±μμμ μμ‘΄νλ©΄ μ λλ€λ κ²μ΄ λ΄ν¬λμ΄ μμ΅λλ€. νμ μΆμνμ μμ‘΄νλλ‘ λ§λ€μ΄μΌ ν©λλ€. κ·Έλ°λ° λλ체 μ΄κ² λ¬΄μ¨ μ리μΌκΉμ? PizzaStoreλ "κ³ μμ€ κ΅¬μ±μμ"λΌκ³ ν μ μκ³ , νΌμ ν΄λμ€λ€μ "μ μμ€ κ΅¬μ±μμ"λΌκ³ ν μ μμ΅λλ€. PizzaStore ν΄λμ€λ ꡬμ νΌμ ν΄λμ€λ€μ μμ‘΄νκ³ μλ€λ κ²μ νμ€νκ² μ μ μμ΅λλ€.
μμ‘΄μ± λ€μ§κΈ° μμΉμ μνλ©΄, ꡬμ ν΄λμ€μ²λΌ ꡬ체μ μΈ κ²μ΄ μλ μΆμ ν΄λμ€λ μΈν°νμ΄μ€μ κ°μ΄ μΆμμ μΈ κ²μ μμ‘΄νλ μ½λλ₯Ό λ§λ€μ΄μΌ ν©λλ€. μ΄ μλμ κ³ μμ€ λͺ¨λκ³Ό μ μμ€ λͺ¨λμ λͺ¨λ μ μ©λ μ μμ΅λλ€.
# μΆκ° μ€λͺ
κ³ μμ€ κ΅¬μ±μμλ λ€λ₯Έ μ μμ€ κ΅¬μ±μμμ μν΄ μ μλλ νλμ΄ λ€μ΄μλ ꡬμ±μμλ₯Ό λ»ν©λλ€.
μλ₯Ό λ€μ΄, PizzaStoreμ νλμ νΌμμ μν΄ μ μλκΈ° λλ¬Έμ, PizzaStoreλ κ³ μμ€ κ΅¬μ±μμλΌκ³ ν μ μμ΅λλ€. PizzaStoreμμλ λ€μν νΌμ κ°μ²΄λ₯Ό λ§λ€κ³ , νΌμλ₯Ό μ€λΉνκ³ , κ΅½κ³ , μλ₯΄κ³ , ν¬μ₯νμ£ . μ΄λ PizzaStoreμμ μ¬μ©νλ νΌμ κ°μ²΄λ€μ μ μμ€ κ΅¬μ±μμλΌκ³ ν μ μμ κ²μ λλ€.
# μ¬νκ² μμ‘΄μ μΈ PizzaStore
μ¬νκ² μμ‘΄μ μΈ PizzaStoreμ κ°μ₯ ν° λ¬Έμ μ μ λͺ¨λ μ’ λ₯μ νΌμμ μμ‘΄νλ€λ μ μ λλ€. orderPizza() λ©μλμμ ꡬμ νμμ μΈμ€ν΄μ€λ₯Ό μ§μ λ§λ€κΈ° λλ¬Έμ΄μ£ . λ°°μ΄λλ‘ ν©ν 리 λ©μλ ν¨ν΄μ μ μ©νκ³ λλ©΄ λ€μ΄μ΄κ·Έλ¨μ΄ λ€μκ³Ό κ°μ΄ λ°λκ² λ©λλ€.
ν©ν 리 λ©μλ ν¨ν΄μ μ μ©νκ³ λλ©΄ κ³ μμ€ κ΅¬μ±μμμΈ PizzaStoreμ μ μμ€ κ΅¬μ±μμμΈ νΌμ κ°μ²΄λ€μ΄ λͺ¨λ μΆμ ν΄λμ€μΈ Pizzaμ μμ‘΄νκ² λλ€λ κ²μ μ μ μμ΅λλ€. ν©ν 리 λ©μλ ν¨ν΄μ΄ μμ‘΄μ± λ€μ§κΈ° μμΉμ μ€μνκΈ° μν΄ μΈ μ μλ μ μΌν κΈ°λ²μ μλλλ€. νμ§λ§ κ°μ₯ μ ν©ν λ°©λ² κ°μ΄λ° νλλΌκ³ λ ν μ μμ΅λλ€.
# κ°μ΄λ λΌμΈ
λ€μκ³Ό κ°μ κ°μ΄λ λΌμΈμ λ°λ₯΄λ©΄ μμ‘΄μ± λ€μ§κΈ° μμΉμ μλ°°λλ κ°μ²΄μ§ν₯ λμμΈμ νΌνλ λ° λμμ΄ λ©λλ€.
# μ΄λ€ λ³μμλ ꡬμ ν΄λμ€μ λν λ νΌλ°μ€λ₯Ό μ μ₯νμ§ λ§μλ€.
new μ°μ°μλ₯Ό μ¬μ©νλ©΄ ꡬμ ν΄λμ€μ λν λ νΌλ°μ€λ₯Ό μ¬μ©νκ² λλ κ²μ λλ€. ν©ν 리λ₯Ό μ¨μ ꡬμ ν΄λμ€μ λν λ νΌλ°μ€λ₯Ό λ³μμ μ μ₯νλ μΌμ 미리 λ°©μ§ν©μλ€.
# ꡬμ ν΄λμ€μμ μ λλ ν΄λμ€λ₯Ό λ§λ€μ§ λ§μλ€.
ꡬμ ν΄λμ€μμ μ λλ ν΄λμ€λ₯Ό λ§λ€λ©΄ νΉμ ꡬμ ν΄λμ€μ μμ‘΄νκ² λ©λλ€. μΈν°νμ΄μ€λ μΆμ ν΄λμ€μ²λΌ μΆμνλ κ²μΌλ‘λΆν° ν΄λμ€λ₯Ό λ§λ€μ΄μΌ ν©λλ€.
# λ² μ΄μ€ ν΄λμ€μ μ΄λ―Έ ꡬνλμ΄ μλ λ©μλλ₯Ό μ€λ²λΌμ΄λνμ§ λ§μλ€.
μ΄λ―Έ ꡬνλμ΄ μλ λ©μλλ₯Ό μ€λ²λΌμ΄λνλ€λ κ²μ μ μ΄λΆν° λ² μ΄μ€ ν΄λμ€κ° μ λλ‘ μΆμνλ κ²μ΄ μλμλ€κ³ λ³Ό μ μμ΅λλ€. λ² μ΄μ€ ν΄λμ€μμ λ©μλλ₯Ό μ μν λλ λͺ¨λ μλΈν΄λμ€μμ 곡μ ν μ μλ€λ κ²λ§ μ μν΄μΌ ν©λλ€.
# Conclusion
Factory Patternμ λ§€μ° μ€μνκ³ νμ©λκ° λμ ν¨ν΄μλ©° κ·Έλ§νΌ λ΄μ©λ λ°©λν©λλ€. λ€μ μ₯μμλ μν©μ μ’ λ μΈλΆννμ¬ λ¬Έμ μ μ μ°Ύκ³ Abstract Factory PatternμΌλ‘ κ·Έ λ¬Έμ λ₯Ό ν΄κ²°ν΄λ³΄λλ‘ νκ² μ΅λλ€.
# References
- Head First Design Patterns