팩토리 패턴은 추상화된 부모 클래스를 활용해서 다양한 파생 클래스들을 공장처럼 찍어내듯 만들어내는 것을 말합니다. real world 예시로는 자동차, 커피, 피자 등 특정 제품을 만들 때 공통된 부분을 추상화된 부모 클래스로 생성하고 제품들 마다 커스텀하게 만들어야 하는 부분들은 하위 클래스에서 지정해주는 것을 들 수 있습니다.
팩토리 패턴은 크게 3종류로 분류해볼 수 있습니다.
이번 포스팅에서는 Simple Factory를 다뤄보도록 하겠습니다.
Simple Factory는 객체들의 생성을 책임지고 관리하는 팩토리를 만들어서 확장 및 관리를 용이하게 해주는 방식입니다. Simple Factory는 단순하게 객체를 생성하고 넘겨주는 작업만 합니다. 일반적으로 Simple Factory는 패턴이라고 부르진 않습니다.
CoffeeFactory 클래스는 커피 종류에 따라서 해당 객체를 생성하는 역할만 맡고 있습니다.
import { Cafe, CoffeeFactory } from "./designPatterns/fatory";
const factory = new CoffeeFactory();
const starbucks = new Cafe("starbucks", factory);
// 스타벅스 커피숍 객체를 생성하고 카페이름과 factory 객체를 인자로 전달합니다.
CoffeeFactory 객체는 매개변수로 받은 커피의 종류에 따라 객체를 생성하는 역할만 맡고 있습니다.
export class CoffeeFactory {
createCoffee(name) {
switch (name) {
case "espresso":
return new EspressoCoffee();
case "americano":
return new AmericanoCoffee();
case "vienna":
return new ViennaCoffee();
case "caffe latte":
return new CaffeLatteCoffee();
case "vanilla latte":
return new VanillaLatteCoffee();
case "caramel latte":
return new CaramelLatteCoffee();
case "caramel macchiato":
return new CaramelMacchiatoCoffee();
case "cappuccino":
return new CappuccinoCoffee();
case "caffe mocha":
return new CaffeMochaCoffee();
case "mochaccino":
return new MochaccinoCoffee();
default:
return null;
}
}
}
CoffeeFactory 객체를 constructor에서 변수에 저장하고, createCoffee 메소드를 이용해서 coffee 객체를 만들고 필요한 각 메소드를 순서대로 호출합니다.
export class Cafe {
constructor(name, factory) {
this.name = name;
this.factory = factory;
}
orderCoffee(coffeeName) {
const coffee = this.factory.createCoffee(coffeeName);
coffee.prepare();
coffee.box();
coffee.pourLiquid();
return coffee;
}
}
커피숍에 반드시 있어야할 Coffee 클래스입니다.
class Coffee {
getName() {
return this.name;
}
prepare() {
console.log("------------------------------");
console.log(`${this.name} 메뉴를 준비 중 입니다.`);
this.extractEspresso();
}
extractEspresso() {
console.log("에스프레소 추출중입니다...");
}
pourLiquid() {
if (typeof this.liquid === "undefined") {
return;
}
console.log(`${this.liquid}을/를 붓습니다.`);
}
box() {
console.log("커피를 포장하는 중입니다..");
}
}
class EspressoCoffee extends Coffee {
constructor() {
super();
this.name = "에스프레소";
}
}
class AmericanoCoffee extends Coffee {
constructor() {
super();
this.name = "아메리카노";
this.liquid = "물";
}
}
class CaffeLatteCoffee extends Coffee {
constructor() {
super();
this.name = "카페라떼";
this.liquid = "우유";
}
}
------------------------------
에스프레소 메뉴를 준비 중 입니다.
에스프레소 추출중입니다...
커피를 포장하는 중입니다..
주문하신 에스프레소 나왔습니다!
------------------------------
아메리카노 메뉴를 준비 중 입니다.
에스프레소 추출중입니다...
커피를 포장하는 중입니다..
물을/를 붓습니다.
주문하신 아메리카노 나왔습니다!
------------------------------
카페라떼 메뉴를 준비 중 입니다.
에스프레소 추출중입니다...
커피를 포장하는 중입니다..
우유을/를 붓습니다.
주문하신 카페라떼 나왔습니다!
이렇게 심플 팩토리 구조는 단순합니다. Cafe 클래스는 직접 커피 객체를 생성하지 않고 CoffeeFactory를 이용하여 커피를 만드는 구조로 되어 있습니다. 다음 포스팅에서는 Factory Method를 다루도록 하겠습니다.