Abstract Factory Pattern (추상 팩토리 패턴)
22 Jul 2019 | design pattern programming software추상 팩토리 패턴이란?
- 구체적인 클래스에 의존하지 않고 서로 연관되거나 의존적인 객체들의 조합을 만드는 인터페이스를 제공하는 패턴이다.
- 많은 수의 연관된 서브 클래스를 특정 그룹으로 묶어 한번에 교체할 수 있도록 만든 디자인 패턴이다.
추상 팩토리 패턴의 장단점
장점
- 인터페이스 보다는 구조체에 접근할 수 있는 코드를 제공한다.
- 확장에 매우 용이한 패턴으로 쉽게 다른 서브 클래스들을 확장할 수 있다.
- 기존 팩토리 패턴의 if-else 로직에서 벗어날 수 있게 해준다.
단점
-
새로운 종류의 제품을 제공하기 힘들다. AbstractProduct나 AbstractFactory에 새로운 항목을 추가해야 하는 경우가 생길수 있는데 이것은 인터페이스를 수정해야 한다.
-
객체를 만들때 객체지향 원칙인 LSP (Liskov Substitution principle) 를 해칠 수 있기 때문에 주의해야 한다.
UML 및 클래스 다이어그램

![]()
![]()
추상 팩토리 패턴을 사용하는 경우
대표적인 예로, OS에 따라 달라지는 GUI 변경과 같은 설정의 변경이 필요할 때 사용할 수 있다.
Sample
import java.util.Random;
interface GUIFactory {
Button createButton();
}
class WinFactory implements GUIFactory {
@Override
public Button createButton() {
return new WinButton();
}
}
class OSXFactory implements GUIFactory {
@Override
public Button createButton() {
return new OSXButton();
}
}
interface Button {
void paint();
}
class WinButton implements Button {
public void paint() {
System.out.println("WinButton");
}
}
class OSXButton implements Button {
public void paint() {
System.out.println("OSXButton");
}
}
class Application {
Application(GUIFactory factory) {
Button button = factory.createButton();
button.paint();
}
}
public class Main {
public static void main(String[] args) {
int randomAppearance = new Random().nextInt(2);
new Application(createOsSpecificFactory(randomAppearance));
}
private static GUIFactory createOsSpecificFactory(int appearance) {
switch (appearance) {
case 0:
return new OSXFactory();
case 1:
return new WinFactory();
default:
throw new IllegalArgumentException("unknown " + appearance);
}
}
}
다른 패턴들과 비교
- factory 패턴과 다른 점은 factory를 좀 더 생산적으로 만들어 낼 수 있다는 점이다.
- 인풋에 대해 factory class 안에서 if-else로 다른 sub-class를 반환하는 일련의 과정을 생략할 수 있다.
팩토리 메서드 패턴과 너무 헷갈리는데, 뭐가 다를까?
팩토리 메서드 패턴과 팩토리 패턴의 차이 (StackOverflow) 많은 사람들이 헷갈려 하는 부분이고, 스택오버플로우에 잘 정리가 되어 있다.
팩토리 메서드 패턴
- 하나의 메소드이다
- 하나의 아이템을 만들기 위해 쓰인다
- 상속(Inheritance)을 사용하고 객체 생성을 핸들링하기 위하여 서브클래스에 의존한다.
class A {
public void doSomething() {
Foo f = makeFoo();
f.whatever();
}
protected Foo makeFoo() {
return new RegularFoo();
}
}
class B extends A {
protected Foo makeFoo() {
//subclass is overriding the factory method
//to return something different
return new SpecialFoo();
}
}
추상 팩토리 패턴
- 객체이다
- 관련된 아이템들의 묶음을 만들기 위하여 만들어진다.
- 여러개의 팩토리 메소드를 가지고 있다.
- 객체 합성(Composition)을 통하여 객체 생성을 한다.
- 객체를 생성 가능한 객체를 만드는 추상 메소드를 가진 베이스 클래스를 만든다.
class A {
private Factory factory;
public A(Factory factory) {
this.factory = factory;
}
public void doSomething() {
//The concrete class of "f" depends on the concrete class
//of the factory passed into the constructor. If you provide a
//different factory, you get a different Foo object.
Foo f = factory.makeFoo();
f.whatever();
}
}
interface Factory {
Foo makeFoo();
Bar makeBar();
Aycufcn makeAmbiguousYetCommonlyUsedFakeClassName();
}
가장 큰 차이점은 각 패턴의 목적이 팩토리 메서드 패턴은 객체를 생성하는데 있지 않고, 추상 팩토리 패턴은 객체를 생성해야 한다는 것이다.
참고한 페이지
- 위키피디아
- https://yukariko.github.io/designpattern/2016/08/19/abstract-factory.html
- https://ko.wikipedia.org/wiki/%EC%B6%94%EC%83%81%ED%8C%A9%ED%86%A0%EB%A6%AC%ED%8C%A8%ED%84%B4
- https://donxu.tistory.com/entry/Abstract-Factory-Pattern%EC%B6%94%EC%83%81-%ED%8C%A9%ED%86%A0%EB%A6%AC-%ED%8C%A8%ED%84%B4