자바 추상 팩토리 디자인 패턴 심층 분석 (UML 포함)

추상 팩토리 패턴의 개념 이해

소프트웨어 개발에서 유사한 제품군을 일관성 있게 생성해야 할 때 사용하는 대표적인 생성형 디자인 패턴 중 하나가 바로 추상 팩토리(abstract factory) 패턴이다. 이 패턴은 관련된 객체들의 집합을 추상화하여, 특정 구체적인 클래스에 의존하지 않고도 일관된 방식으로 객체를 생성할 수 있도록 한다.

핵심 구성 요소

  • AbstractFactory: 여러 종류의 제품을 생성할 수 있는 인터페이스를 정의한다. 실제 어떤 제품이 만들어지는지에 대한 세부 정보는 포함하지 않는다.
  • ConcreteFactory: 추상 팩토리를 구현하며, 특정 제품군을 생성하는 책임을 진다. 예를 들어 Windows 스타일 UI 요소를 전담 생성하거나, 모티프(Motif) 스타일 요소를 제공할 수 있다.
  • AbstractProduct: 각각의 제품 유형에 대한 공통 인터페이스 또는 추상 클래스다. 예: 버튼(Button), 텍스트박스(TextBox).
  • ConcreteProduct: 구체적인 제품 클래스로, 추상 제품을 상속받아 실제 기능과 시각적 특성을 구현한다.

실제 사례 기반 설명

예를 들어 GUI 프레임워크에서 사용자가 선택한 테마(Windows/Motif)에 따라 버튼과 입력창이 모두 해당 테마 스타일을 따라야 하는 경우를 생각해보자. 이때 모든 UI 요소를 하나의 일관된 스타일로 조합하여 생성해야 하며, 추상 팩토리는 이를 위한 해결책을 제공한다.

코드 구현

1. 추상 제품 클래스 정의

abstract class Button {
    public abstract void render();
}

abstract class TextBox {
    public abstract void display();
}

2. 구체적인 제품 클래스들

class WindowsButton extends Button {
    @Override
    public void render() {
        System.out.println("Rendering Windows-style button");
    }
}

class MotifButton extends Button {
    @Override
    public void render() {
        System.out.println("Rendering Motif-style button");
    }
}

class WindowsTextBox extends TextBox {
    @Override
    public void display() {
        System.out.println("Displaying Windows-style text box");
    }
}

class MotifTextBox extends TextBox {
    @Override
    public void display() {
        System.out.println("Displaying Motif-style text box");
    }
}

3. 추상 팩토리 인터페이스

interface UIFactory {
    Button createButton();
    TextBox createTextBox();
}

4. 구체적인 팩토리 클래스들

class WindowsUIFactory implements UIFactory {
    @Override
    public Button createButton() {
        return new WindowsButton();
    }

    @Override
    public TextBox createTextBox() {
        return new WindowsTextBox();
    }
}

class MotifUIFactory implements UIFactory {
    @Override
    public Button createButton() {
        return new MotifButton();
    }

    @Override
    public TextBox createTextBox() {
        return new MotifTextBox();
    }
}

5. 클라이언트 코드 – 다이얼로그 예시

class UIDialog {
    private UIFactory factory;
    private Button button;
    private TextBox inputField;

    public void setUIFactory(UIFactory factory) {
        this.factory = factory;
    }

    public void initializeComponents() {
        button = factory.createButton();
        inputField = factory.createTextBox();
        button.render();
        inputField.display();
    }
}

6. 테스트 실행

public class Application {
    public static void main(String[] args) {
        UIDialog dialog = new UIDialog();

        // Windows 스타일 UI 생성
        dialog.setUIFactory(new WindowsUIFactory());
        dialog.initializeComponents();

        // Motif 스타일 UI 생성
        dialog.setUIFactory(new MotifUIFactory());
        dialog.initializeComponents();
    }
}

출력 결과

Rendering Windows-style button
Displaying Windows-style text box
Rendering Motif-style button
Displaying Motif-style text box

연습 문제: 계절별 게임 환경 생성기

게임 내에서 겨울과 여름 테마에 맞춰 나무와 바닥 재질이 다르게 표현되어야 한다고 가정하자. 각 테마에 따른 객체들을 일관성 있게 생성하기 위해 추상 팩토리 패턴을 적용한다.

요구사항

  • 나무(Tree): WinterTree, SummerTree
  • 바닥(Floor): WinterFloor, SummerFloor
  • 팩토리: WinterEnvironmentFactory, SummerEnvironmentFactory

해결 코드

abstract class Tree { public abstract void grow(); }
abstract class Floor { public abstract void texture(); }

class WinterTree extends Tree {
    @Override public void grow() { System.out.println("Snow-covered pine tree"); }
}
class SummerTree extends Tree {
    @Override public void grow() { System.out.println("Lush green oak tree"); }
}
class WinterFloor extends Floor {
    @Override public void texture() { System.out.println("Icy ground surface"); }
}
class SummerFloor extends Floor {
    @Override public void texture() { System.out.println("Grassy terrain"); }
}

interface EnvironmentFactory {
    Tree createTree();
    Floor createFloor();
}

class WinterEnvironmentFactory implements EnvironmentFactory {
    public Tree createTree() { return new WinterTree(); }
    public Floor createFloor() { return new WinterFloor(); }
}

class SummerEnvironmentFactory implements EnvironmentFactory {
    public Tree createTree() { return new SummerTree(); }
    public Floor createFloor() { return new SummerFloor(); }
}

class GameScene {
    private EnvironmentFactory factory;
    private Tree sceneryTree;
    private Floor ground;

    public void loadEnvironment(EnvironmentFactory factory) {
        this.factory = factory;
        this.sceneryTree = factory.createTree();
        this.ground = factory.createFloor();
        sceneryTree.grow();
        ground.texture();
    }
}

// 테스트
public class GameLauncher {
    public static void main(String[] args) {
        GameScene scene = new GameScene();

        scene.loadEnvironment(new WinterEnvironmentFactory());
        scene.loadEnvironment(new SummerEnvironmentFactory());
    }
}

출력

Snow-covered pine tree
Icy ground surface
Lush green oak tree
Grassy terrain

패턴의 주요 특징 정리

  1. 관련 제품 그룹 생성: 서로 연관된 여러 객체를 일괄적으로 생성할 수 있으며, 이들 간의 호환성과 스타일 통일성이 보장된다.
  2. 의존성 역전: 클라이언트는 추상 인터페이스에만 의존하므로, 새로운 제품군 추가 시 기존 코드 수정 없이 확장이 가능하다 (OCP 원칙 준수).
  3. 런타임 유연성: 애플리케이션 설정이나 사용자 입력에 따라 적절한 팩토리를 주입함으로써 전체 인터페이스 스타일을 동적으로 전환할 수 있다.

태그: java 디자인패턴 추상팩토리 생성형패턴 uml

6월 22일 18:33에 게시됨