PHpullh
학습 라이브러리/Java/Singleton & Factory Method & Abstract Factory

JAVA · 디자인패턴

Singleton & Factory Method & Abstract Factory

GoF 생성 패턴의 핵심 3가지를 현대적 Java 문법으로 구현합니다.

디자인패턴중급Singletonenum SingletonFactory MethodAbstract FactoryGoF

핵심 설명

GoF 생성 패턴의 핵심 3가지를 현대적 Java 문법으로 구현합니다.

Java code

import java.util.*;

// Singleton — enum 방식 (가장 안전)
enum AppConfig {
    INSTANCE;

    private final Map<String, String> props = new HashMap<>();

    public void set(String key, String value) { props.put(key, value); }
    public String get(String key) { return props.getOrDefault(key, ""); }
}

// Factory Method 패턴
interface Logger {
    void log(String msg);
}

class ConsoleLogger implements Logger {
    public void log(String msg) { System.out.println("[CONSOLE] " + msg); }
}
class FileLogger implements Logger {
    public void log(String msg) { System.out.println("[FILE] " + msg); }
}

// 정적 팩토리 메서드
class LoggerFactory {
    public static Logger create(String type) {
        return switch (type) {
            case "console" -> new ConsoleLogger();
            case "file"    -> new FileLogger();
            default        -> throw new IllegalArgumentException("Unknown: " + type);
        };
    }
}

// Abstract Factory — 관련 객체군 생성
interface Button { void render(); }
interface Dialog { void show(); }

record WindowsButton() implements Button {
    public void render() { System.out.println("[Windows] 버튼"); }
}
record MacButton() implements Button {
    public void render() { System.out.println("[Mac] 버튼"); }
}

interface UIFactory {
    Button createButton();
    Dialog createDialog();
}

class WindowsFactory implements UIFactory {
    public Button createButton() { return new WindowsButton(); }
    public Dialog createDialog() { return () -> System.out.println("[Windows] 다이얼로그"); }
}

class Main {
    public static void main(String[] args) {
        // Singleton (enum)
        AppConfig.INSTANCE.set("env", "production");
        System.out.println(AppConfig.INSTANCE.get("env"));

        // Factory Method
        Logger logger = LoggerFactory.create("console");
        logger.log("테스트 메시지");

        // Abstract Factory
        UIFactory factory = new WindowsFactory();
        factory.createButton().render();
        factory.createDialog().show();
    }
}

학습 팁

Enum Singleton은 직렬화 안전성과 리플렉션 공격에 강해 Effective Java가 권장하는 최선의 Singleton 구현 방법입니다.

주의할 점

전통적 Singleton에서 double-checked locking 시 필드에 volatile을 빠뜨리면 CPU 명령 재정렬로 인해 NPE가 발생할 수 있습니다.

자주 묻는 질문

Singleton & Factory Method & Abstract Factory란 무엇인가요?

GoF 생성 패턴의 핵심 3가지를 현대적 Java 문법으로 구현합니다.

Singleton & Factory Method & Abstract Factory 학습 시 주의할 점은 무엇인가요?

전통적 Singleton에서 double-checked locking 시 필드에 volatile 을 빠뜨리면 CPU 명령 재정렬로 인해 NPE가 발생할 수 있습니다.