추상 팩토리 패턴은 객체 생성의 유연성을 제공하는 디자인 패턴으로, 서로 관련된 객체들을 일관된 방식으로 생성할 수 있도록 돕는다. 구체적인 클래스에 의존하지 않고 제품군을 정의하고 이를 생성하는 인터페이스를 제공함으로써, 클라이언트 코드가 구체적인 제품의 생성 방식에 대해 알 필요가 없도록 한다. 이 글에서는 정의·구성 요소·동작 원리·실전 예제·FAQ·관련 기술·참고 문헌까지 정리한다.
개요
추상 팩토리 패턴의 정의
추상 팩토리 패턴은 구체적인 클래스에 의존하지 않고 관련된 객체들의 집합을 생성하는 인터페이스를 제공하는 생성 패턴(Creational Pattern)이다. 클라이언트는 어떤 구체 클래스의 인스턴스를 생성할지 결정하지 않고, 팩토리 인터페이스를 통해 객체를 생성한다. GoF(Gamma et al., 1994)의 정의는 다음과 같다.
“an interface for creating families of related or dependent objects without specifying their concrete classes.”
패턴의 필요성 및 사용 사례
- UI 라이브러리: 운영 체제(Windows, macOS, Linux)에 따라 다른 버튼·텍스트박스·체크박스를 생성할 때, 각 OS에 맞는 UI 요소를 한 번에 맞춰 생성할 수 있다.
- 가구 쇼핑몰 시뮬레이터: 의자, 소파, 커피 테이블이라는 제품군을 현대식·빅토리안·아르데코 등 스타일별로 일관되게 생성할 때 적합하다.
- 엘리베이터 부품: 제조사별로 Motor, Door 등 부품군을 바꿔 끼우되, 클라이언트 코드는 동일하게 유지할 수 있다.
장점과 단점
| 장점 | 단점 |
|---|---|
| 새로운 제품 변형 추가 시 기존 코드 수정 없이 새 팩토리 클래스만 추가 가능 | 팩토리·제품 클래스가 늘어나 시스템 복잡도 증가 가능 |
| 클라이언트가 구체 클래스에 의존하지 않아 재사용성·테스트 용이 | 새 제품 종류(메서드) 추가 시 추상 팩토리 인터페이스 변경 필요 |
추상 팩토리 패턴의 구성 요소
| 역할 | 설명 |
|---|---|
| AbstractFactory | 제품 객체를 생성하기 위한 인터페이스. 여러 제품 생성 메서드를 선언한다. |
| ConcreteFactory | AbstractFactory를 구현하며, 특정 제품군(예: 현대식 가구)에 대한 구체 객체를 생성한다. |
| AbstractProduct | 생성될 제품의 공통 인터페이스. 제품이 가져야 할 메서드를 정의한다. |
| ConcreteProduct | AbstractProduct를 구현한 실제 제품 클래스(예: ModernChair, VictorianSofa). |
아래는 GUI 예제 기준의 클래스 다이어그램이다.
classDiagram
class GuiFactory {
<>
"+create_button(): Button"
}
class Button {
<>
"+render()"
}
class WindowsButton {
"+render()"
}
class MacOsButton {
"+render()"
}
class WindowsFactory {
"+create_button(): Button"
}
class MacOsFactory {
"+create_button(): Button"
}
GuiFactory <|-- WindowsFactory
GuiFactory <|-- MacOsFactory
Button <|-- WindowsButton
Button <|-- MacOsButton
구성 요소 상세
AbstractFactory
제품 객체를 생성하기 위한 인터페이스를 정의한다. 다양한 제품을 생성하는 메서드를 포함하며, 클라이언트는 이 인터페이스만으로 제품을 요청한다.
ConcreteFactory
AbstractFactory를 구현하는 클래스로, 특정 제품군에 대한 구체 객체를 생성한다. 예: 현대식 가구 팩토리는 현대식 의자·소파·커피 테이블을 생성한다.
AbstractProduct
생성될 제품의 공통 인터페이스로, 제품이 제공해야 할 메서드를 정의한다. 클라이언트는 이 인터페이스만 알면 된다.
ConcreteProduct
AbstractProduct를 구현한 실제 제품 클래스다. 현대식 의자, 빅토리안 소파, 아르데코 커피 테이블 등이 해당한다.
일반적인 추상 팩토리 구조를 제품 A/B와 두 가지 변형으로 나타낸 다이어그램은 다음과 같다.
classDiagram
class AbstractFactory {
"+createProductA(): AbstractProductA"
"+createProductB(): AbstractProductB"
}
class ConcreteFactory1 {
"+createProductA(): ConcreteProductA1"
"+createProductB(): ConcreteProductB1"
}
class ConcreteFactory2 {
"+createProductA(): ConcreteProductA2"
"+createProductB(): ConcreteProductB2"
}
class AbstractProductA {
"+operationA(): void"
}
class ConcreteProductA1 {
"+operationA(): void"
}
class ConcreteProductA2 {
"+operationA(): void"
}
class AbstractProductB {
"+operationB(): void"
}
class ConcreteProductB1 {
"+operationB(): void"
}
class ConcreteProductB2 {
"+operationB(): void"
}
AbstractFactory <|-- ConcreteFactory1
AbstractFactory <|-- ConcreteFactory2
AbstractProductA <|-- ConcreteProductA1
AbstractProductA <|-- ConcreteProductA2
AbstractProductB <|-- ConcreteProductB1
AbstractProductB <|-- ConcreteProductB2
추상 팩토리 패턴의 동작 원리
객체 생성 과정
- 클라이언트는 추상 팩토리 인터페이스를 통해 제품을 요청한다.
- 실행 시점 또는 설정에 따라 구체 팩토리가 선택·인스턴스화된다.
- 선택된 팩토리가 요청된 제품의 인스턴스를 생성해 반환한다.
클라이언트는 구체적인 제품 클래스를 알 필요가 없고, 추상 팩토리와 추상 제품 인터페이스만 사용한다.
클라이언트와 팩토리의 관계
클라이언트는 추상 팩토리 타입에만 의존한다. 새 제품 변형이 추가되어도 클라이언트 코드는 수정하지 않아도 되며, 이는 확장성과 유지보수성을 높인다.
환경에 따른 팩토리 선택
OS·설정·환경 변수 등에 따라 적절한 ConcreteFactory를 선택해 주입한다. 예시는 다음과 같다.
| |
동작 흐름을 단순화한 다이어그램은 아래와 같다.
graph TD
ClientNode["클라이언트"]
AbstractFactoryNode["추상 팩토리"]
ConcreteFactoryNode["구체적인 팩토리"]
ConcreteProductNode["구체적인 제품"]
ClientNode -->|"요청"| AbstractFactoryNode
AbstractFactoryNode -->|"생성 위임"| ConcreteFactoryNode
ConcreteFactoryNode -->|"생성"| ConcreteProductNode
ConcreteProductNode -->|"반환"| ClientNode
예제 1: GUI 버튼 (Python)
추상 제품 Button, 추상 팩토리 GUIFactory, OS별 구체 구현으로 클라이언트가 OS에 맞는 버튼을 받는 예제다.
| |
예제 2: 가구 쇼핑몰 시뮬레이터
의자·소파·커피 테이블이라는 제품군을 현대식·빅토리안 변형으로 일관되게 생성하는 예제다.
| |
가구 팩토리 구조를 나타낸 클래스 다이어그램이다.
classDiagram
class FurnitureFactory {
"+create_chair()"
"+create_sofa()"
}
class ModernFurnitureFactory {
"+create_chair()"
"+create_sofa()"
}
class VictorianFurnitureFactory {
"+create_chair()"
"+create_sofa()"
}
class Chair {
"+sit_on()"
}
class Sofa {
"+lie_on()"
}
class ModernChair {
"+sit_on()"
}
class VictorianChair {
"+sit_on()"
}
class ModernSofa {
"+lie_on()"
}
class VictorianSofa {
"+lie_on()"
}
FurnitureFactory <|-- ModernFurnitureFactory
FurnitureFactory <|-- VictorianFurnitureFactory
ModernFurnitureFactory --> ModernChair
ModernFurnitureFactory --> ModernSofa
VictorianFurnitureFactory --> VictorianChair
VictorianFurnitureFactory --> VictorianSofa
예제 3: 엘리베이터 부품
제조사별로 버튼·모니터 등 부품군을 바꿔 끼우는 예제다.
| |
FAQ
Q1. 추상 팩토리 패턴과 팩토리 메서드 패턴의 차이는?
- 팩토리 메서드: 한 종류의 제품을 생성하는 데 초점을 두고, 서브클래스가 구체 제품을 결정한다.
- 추상 팩토리: 관련된 여러 제품을 한 번에 생성하는 인터페이스를 제공하며, 한 팩토리가 제품군 전체를 담당한다. 내부적으로 팩토리 메서드들을 조합해 구현하는 경우가 많다.
Q2. 사용 시 주의사항은?
- 제품군과 각 제품 간 관계를 명확히 정의해야 한다.
- 새 제품 변형 추가 시 기존 클라이언트를 건드리지 않도록 인터페이스만 활용한다.
- 제품 종류(메서드)가 자주 바뀌면 추상 팩토리 인터페이스가 자주 변경되므로, 그런 경우 빌더·프로토타입 등과의 조합을 고려한다.
Q3. 새 제품 변형을 추가하려면?
- 새 변형에 맞는
ConcreteProduct클래스들을 추가한다. AbstractFactory를 구현하는 새ConcreteFactory를 추가한다.- 초기화/설정 코드에서 환경에 따라 이 새 팩토리를 선택하도록 한다. 클라이언트 코드는 수정하지 않는다.
Q4. 성능은?
객체 생성이 인터페이스를 한 번 더 거치므로 이론적으로는 오버헤드가 있으나, 대부분의 애플리케이션에서는 무시할 수준이다. 유연성과 유지보수성 이점이 더 크다.
관련 기술
- 생성 패턴(Creational Patterns): 추상 팩토리, 팩토리 메서드, 싱글턴, 빌더, 프로토타입 등으로 객체 생성 방식을 캡슐화한다.
- 싱글턴 패턴: 구체 팩토리 인스턴스를 앱 전체에서 하나만 쓰고 싶을 때, ConcreteFactory를 싱글턴으로 구현하는 경우가 많다.
- 템플릿 메서드 패턴: 제품 생성 과정의 골격을 정하고, 일부 단계만 서브클래스에서 구현할 때 함께 쓰일 수 있다.
아래는 싱글턴과 템플릿 메서드 패턴의 구조 예시다. (추상 팩토리와는 별개 패턴이다.)
classDiagram
class SingletonClass {
"- instance: SingletonClass"
"+ getInstance(): SingletonClass"
}
class AbstractClass {
"+ templateMethod()"
"+ stepOne()"
"+ stepTwo()"
}
class ConcreteClass {
"+ stepOne()"
"+ stepTwo()"
}
AbstractClass <|-- ConcreteClass
결론
- 추상 팩토리 패턴은 관련 객체 제품군을 구체 클래스에 의존하지 않고 일관되게 생성할 수 있게 해 준다.
- UI 테마, 가구 스타일, 제조사별 부품처럼 변형(family) 이 여러 개이고, 한 번 선택한 변형끼리만 맞춰 쓰는 상황에 적합하다.
- 새 변형 추가는 새 ConcreteFactory와 ConcreteProduct 추가로 해결할 수 있어, 개방-폐쇄 원칙(OCP)에 잘 맞는다.
참고 문헌
- Design Patterns: Elements of Reusable Object-Oriented Software — Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides. 추상 팩토리를 포함한 GoF 패턴의 원전.
- Head First Design Patterns — Eric Freeman 외. 추상 팩토리를 비유와 그림으로 설명한 입문서.
- Refactoring Guru – Abstract Factory — https://refactoring.guru/design-patterns/abstract-factory. 의도·구조·예제·다른 패턴과의 관계 정리.
- Wikipedia – Abstract factory pattern — https://en.wikipedia.org/wiki/Abstract_factory_pattern. 정의·구조·사용 맥락.
- gmlwjd9405 – 추상 팩토리 패턴 — https://gmlwjd9405.github.io/2018/08/08/abstract-factory-pattern.html. 엘리베이터 부품 예제와 팩토리 메서드·싱글턴 조합.
- johngrib – 추상 팩토리 패턴 — https://johngrib.github.io/wiki/pattern/abstract-factory/. Java Collection·URL 사례와 구현 시 고려점.
![Featured image of post [DesignPattern] 추상 팩토리 패턴](/post/2024-08-22-abstract-factory/wordcloud_hu_dc95cc360b5ec795.webp)
![[DesignPattern] Abstract Factory Pattern - 추상 팩토리 패턴](/post/2023-09-22-abstract-factory-pattern/wordcloud_hu_65f05d6bc8b4b7f5.webp)
![[Rust] Comprehensive Rust 무료 강의 정리 및 코스 구조](/post/2022-12-30-comprehensive-rust/wordcloud_hu_d1420ff38434cdb6.webp)
![[Hardware] LattePanda Alpha에 Ubuntu 16.04 LTS 설치 가이드](/post/2018-12-06-install-ubuntu-16.04-on-lattepanda/wordcloud_hu_fc536f8de2cbd4bf.webp)
![[Tutorial] Learn Prompting - 프롬프트 엔지니어링 무료 가이드 정리](/post/2022-12-30-learn-prompting/wordcloud_hu_6a9d105de4834753.webp)
![[Python] 파이썬 객체지향 프로그래밍(OOP) 완전 가이드](/post/2024-11-08-python-oop/wordcloud_hu_a40f6ab90bd32ead.webp)