javascript

디자인 패턴:: Simple Factory - Factory Pattern 1

팩토리 패턴은 추상화된 부모 클래스를 활용해서 다양한 파생 클래스들을 공장처럼 찍어내듯 만들어내는 것을 말합니다. real world 예시로는 자동차, 커피, 피자 등 특정 제품을 만들 때 공통된 부분을 추상화된 부모 클래스로 생성하고 제품들 마다 커스텀하게 만들어야 하는 부분들은 하위 클래스에서 지정해주는 것을 들 수 있습니다.

팩토리 패턴은 크게 3종류로 분류해볼 수 있습니다.

  • Simple Factory
  • Factory Method
  • Abstract Factory

이번 포스팅에서는 Simple Factory를 다뤄보도록 하겠습니다.

Simple Factory


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

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;
    }
  }
}

Cafe Class

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 클래스입니다.

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를 다루도록 하겠습니다.