추상 팩토리 abstract factory 패턴 - 자바스크립트 예제

SW설계
읽는데 4분 소요
처음 쓰여진 날: 2025-09-02
마지막 수정일: 2025-09-02

요약

추상 팩토리 abstract factory 패턴을 자바스크립트 코드와 함께 알아봅니다.

추상 팩토리 (Abstract Factory) 패턴 요약

패턴 종류핵심 키워드
추상 팩토리 (Abstract Factory)조합을 만드는 인터페이스(API) 제공, Kit
추상 팩토리 패턴 감자
추상 팩토리 패턴 감자

추상 팩토리 (Abstract Factory) 패턴

추상 팩토리 패턴은 서로 관련이 있거나 의존적인 객체들의 집합을 생성하기 위한 인터페이스를 제공하되, 구체적인 클래스는 지정하지 않는 패턴입니다. 팩토리 메서드 패턴이 단일 객체를 생성하는 것에 초점을 맞춘다면, 추상 팩토리는 '제품군(Family of Products)'을 생성하는 데 사용됩니다.

가장 흔한 예는 UI 컴포넌트의 테마(Theme)를 관리하는 것입니다. 라이트 모드와 다크 모드에 따라 버튼, 체크박스, 창(Window) 등 여러 UI 요소가 일관된 스타일을 가져야 합니다.

기본 구조

javascript
// Abstract Product A: Button
class Button {
  paint() {
    throw new Error("paint() must be implemented.");
  }
}

// Concrete Product A1: LightButton
class LightButton extends Button {
  paint() {
    console.log("🎨 라이트 테마 버튼을 그립니다. ☀️");
  }
}

// Concrete Product A2: DarkButton
class DarkButton extends Button {
  paint() {
    console.log("🎨 다크 테마 버튼을 그립니다. 🌙");
  }
}

// Abstract Product B: Checkbox
class Checkbox {
  paint() {
    throw new Error("paint() must be implemented.");
  }
}

// Concrete Product B1: LightCheckbox
class LightCheckbox extends Checkbox {
  paint() {
    console.log("✅ 라이트 테마 체크박스를 그립니다. ☀️");
  }
}

// Concrete Product B2: DarkCheckbox
class DarkCheckbox extends Checkbox {
  paint() {
    console.log("✅ 다크 테마 체크박스를 그립니다. 🌙");
  }
}

// Abstract Factory
class GUIFactory {
  createButton() {
    throw new Error("createButton() must be implemented.");
  }
  createCheckbox() {
    throw new Error("createCheckbox() must be implemented.");
  }
}

// Concrete Factory 1: LightThemeFactory
class LightThemeFactory extends GUIFactory {
  createButton() {
    return new LightButton();
  }
  createCheckbox() {
    return new LightCheckbox();
  }
}

// Concrete Factory 2: DarkThemeFactory
class DarkThemeFactory extends GUIFactory {
  createButton() {
    return new DarkButton();
  }
  createCheckbox() {
    return new DarkCheckbox();
  }
}

// Client Code 🎯
function renderUI(factory) {
  const button = factory.createButton();
  const checkbox = factory.createCheckbox();
  button.paint();
  checkbox.paint();
}

// 라이트 테마로 UI 렌더링 ☀️
console.log("--- 라이트 모드 UI ---");
const lightFactory = new LightThemeFactory();
renderUI(lightFactory);
// 🎨 라이트 테마 버튼을 그립니다. ☀️
// ✅ 라이트 테마 체크박스를 그립니다. ☀️

// 다크 테마로 UI 렌더링 🌙
console.log("\n--- 다크 모드 UI ---");
const darkFactory = new DarkThemeFactory();
renderUI(darkFactory);
// 🎨 다크 테마 버튼을 그립니다. 🌙
// ✅ 다크 테마 체크박스를 그립니다. 🌙

팩토리 메서드 vs. 추상 팩토리

  • 팩토리 메서드: 하나의 Creator 클래스가 상속을 통해 하나의 제품을 생성하는 방법을 변경합니다.
  • 추상 팩토리: 여러 제품군을 생성하는 인터페이스를 제공합니다. 클라이언트는 구체적인 제품 클래스를 알 필요 없이, 팩토리만 교체하면 전체 제품군을 한 번에 바꿀 수 있습니다.

추상 팩토리 패턴 중요 키워드

  • 관련 객체들의 '가족(family)'을 생성한다.
  • 클라이언트 코드는 구체적인 클래스에 의존하지 않는다.
  • 전체 제품군을 쉽게 교체할 수 있다.
  • 사용자에게 API를 제공하고, 구체적인 구현은 Concrete Product 클래스에서 이루어진다.

'API 제공'과 '구체적 구현'의 의미

여기서 "사용자에게 API를 제공한다"는 말의 '사용자'는 실제 사람이 아닌, 팩토리를 가져다 쓰는 코드(클라이언트 코드) 를 의미합니다.

  • API 제공 (추상 클래스): GUIFactory, Button, Checkbox 같은 추상 클래스는 일종의 '계약서' 또는 '설명서' 역할을 합니다. 클라이언트 코드(renderUI 함수)는 이 '설명서'만 보고 createButton()이나 paint() 같은 메서드를 호출합니다. 클라이언트는 LightButton이나 DarkButton의 실제 구현을 전혀 알 필요가 없습니다.
  • 구체적 구현 (Concrete 클래스): LightThemeFactoryDarkButton 같은 Concrete 클래스는 '계약서'의 내용을 실제로 이행하는 '실무자'입니다. createButton() 요청이 오면 실제 라이트/다크 테마 버튼 객체를 생성하고, paint() 요청이 오면 실제 테마에 맞는 스타일을 그리는 로직을 수행합니다.

결론적으로, 클라이언트 코드는 구체적인 클래스 이름(LightButton)을 코드에 직접 쓸 필요 없이, 추상적인 '설명서(API)'에만 의존하게 됩니다. 덕분에 팩토리만 교체하면 전체 제품군(테마)을 한 번에 바꿀 수 있는 유연한 구조가 만들어집니다.

문제
구체적인 클래스에 의존하지 않고 서로 연관되거나 의존적인 객체들의 조합을 만드는 인터페이스를 제공하는 패턴으로 이 패턴을 통해 생성된 클래스에서는 사용자에게 인터페이스(API)를 제공하고, 구체적인 구현은 Concrete Product 클래스에서 이루어지는 특징을 갖는 디자인 패턴
보기
답변
정답정답 보기
기출
문제
조합을 만드는 인터페이스(API) 제공하고, Kit이라고 하는 디자인 패턴은?
보기
답변
정답정답 보기