728x90
생성 - 추상 팩토리 패턴
추상 팩토리
- 연관된 여러 객체들을 일관된 방식으로 생성할 때 사용하는 패턴
- 추상 팩토리의 다른 이름은 키트(
Kit
)이다. 테마 별로 각 구현체 집합을 생성할 수 있다.
- 추상 팩토리의 다른 이름은 키트(
팩토리 메서드 패턴은 단일 제품(Only one)을 생성하지만, 추상 팩토리 패턴은 여러 제품군을 생성한다.
생성 방법
-
- 각 제품의 인터페이스를 정의한다.
interface Chair {
void sitOn();
}
interface Sofa {
void lieOn();
}
interface CoffeeTable {
void putCoffee();
}
-
- 제품들을 생성할 추상 팩토리를 생성한다.
- 생성할 각 제품들의 인터페이스를 참조한다.
- 제품들을 생성할 추상 팩토리를 생성한다.
interface FurnitureFactory {
Chair createChair();
Sofa createSofa();
CoffeeTable createCoffeeTable();
}
-
- 구체적인 팩토리들을 생성한다.
- 테마 별 구현체 집합을 생성한다.
- 구체적인 팩토리들을 생성한다.
class ModernFurnitureFactory implements FurnitureFactory {
public Chair createChair() {
return new ModernChair();
}
public Sofa createSofa() {
return new ModernSofa();
}
}
class VintageFurnitureFactory implements FurnitureFactory {
public Chair createChair() {
return new VintageChair();
}
public Sofa createSofa() {
return new VintageSofa();
}
}
-
- 클라이언트
- 클라이언트는 구체적인 구현체 집합을 알지 못한다. 추상 팩토리만 의존한다.
- 클라이언트
class FurnitureStore {
private FurnitureFactory factory;
public FurnitureStore(FurnitureFactory factory) {
this.factory = factory;
}
public void orderFurnitureSet() {
// 팩토리를 통해 각 제품을 생성
Chair chair = factory.createChair();
Sofa sofa = factory.createSofa();
// 등등
}
}
구조
-
- 생성할 제품들의 인터페이스
- 구현체 집합
- 추상 팩토리 (인터페이스)
- 구체 팩토리
- 클라이언트
적용 예시
- 크로스 플랫폼 애플리케이션
- Mac, Window에 쓸 UI 요소
// 제품 인터페이스
public interface Button {
void paint();
}
public interface Checkbox {
public void paint();
}
// 제품 구현체
public class MacButton implements Button {
@Override
public void paint() {
}
}
public class WinButton implements Button {
@Override
public void paint() {
}
}
public class MacCheckbox implements Checkbox {
@Override
public void paint() {
}
}
public class WinCheckbox implements Checkbox{
@Override
public void paint() {
}
}
// 추상 팩토리
public interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
}
// 각 구체 팩토리
public class WinFactory implements GUIFactory {
@Override
public Button createButton() {
return new WinButton();
}
@Override
public Checkbox createCheckbox() {
return new WinCheckbox();
}
}
public class MacFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacButton();
}
@Override
public Checkbox createCheckbox() {
return new MacCheckbox();
}
}
// 클라이언트
public class Application {
private final GUIFactory factory;
private final Button button;
public Application(final GUIFactory factory) {
this.factory = factory;
this.button = factory.createButton();
}
public void paint() {
button.paint();
}
}
// 설정 정보
public class ApplicationConfigurator {
private GUIFactory guiFactory;
public void main() {
Config config = readApplicationConfigFile();
if (config.getOS().equals("Windows")) {
guiFactory = new WinFactory();
} else if (config.getOS().equals("Mac")) {
guiFactory = new MacFactory();
}
Application app = new Application(guiFactory);
}
private Config readApplicationConfigFile() {
return new Config("Windows");
}
}
적용점
- 다양한 제품군이 존재하고, 미리 구체적인 제품군을 알지 못하거나 확장성을 허용하고 싶은 경우
- 종류(테마)별로 제품을 생성하는 코드가 혼재해 있을 경우
- 테마별 제품을 생성하는 메서드(또는 분기문)이 복잡하게 존재할 경우
// 분기문이 혼재된 코드 -> 리팩토링 필요
class UIManager {
Button createButton(String theme) {
if (theme.equals("dark")) {
return new DarkButton();
} else if (theme.equals("light")) {
return new LightButton();
}
}
Checkbox createCheckbox(String theme) {
if (theme.equals("dark")) {
return new DarkCheckbox();
} else if (theme.equals("light")) {
return new LightCheckbox();
}
}
}
이 경우, 추상 팩토리를 선언하고, 테마별로 구체 팩토리를 통해 객체들을 생성한다.
- 추상 팩토리를 적용하여 리팩토링
interface UIFactory {
Button createButton();
Checkbox createCheckbox();
}
class DarkThemeFactory implements UIFactory {
public Button createButton() { return new DarkButton(); }
public Checkbox createCheckbox() { return new DarkCheckbox(); }
}
class LightThemeFactory implements UIFactory {
public Button createButton() { return new LightButton(); }
public Checkbox createCheckbox() { return new LightCheckbox(); }
}
Reference
https://refactoring.guru/design-patterns/abstract-factory
Abstract Factory
Solution The first thing the Abstract Factory pattern suggests is to explicitly declare interfaces for each distinct product of the product family (e.g., chair, sofa or coffee table). Then you can make all variants of products follow those interfaces. For
refactoring.guru
728x90
'설계 > 디자인 패턴' 카테고리의 다른 글
[디자인패턴] 생성 패턴 - 빌더 패턴 (0) | 2025.02.14 |
---|---|
[디자인패턴] 생성 패턴 : 팩토리 메서드 패턴 (1) | 2025.02.12 |
[디자인 패턴] 디자인 패턴이란? (0) | 2025.02.11 |