Design Pattern with Java

1. 싱글톤 패턴(Singleton Pattern)

초코너무조코 2025. 1. 7. 12:34
728x90

싱글톤 패턴(Singleton Pattern)은 객체를 하나만 생성하도록 보장하고, 전역적으로 접근할 수 있는 방법을 제공하는 디자인 패턴입니다. 이는 특정 클래스의 인스턴스가 하나만 존재해야 하는 경우에 유용합니다. 자바에서는 싱글톤 패턴이 널리 사용되며, 데이터베이스 연결, 설정 클래스, 로깅 등 다양한 곳에서 활용됩니다.


싱글톤 패턴의 특징

  1. 단일 인스턴스 보장: 클래스의 인스턴스가 하나만 생성됩니다.
  2. 글로벌 접근: 어디서든 해당 인스턴스에 접근할 수 있습니다.
  3. 메모리 절약: 불필요한 객체 생성을 방지하여 메모리를 절약할 수 있습니다.

싱글톤 패턴 구현 방법

자바에서 싱글톤 패턴을 구현하는 여러 가지 방법이 있습니다. 여기서는 대표적인 구현 방식을 다루겠습니다.


1. Eager Initialization (즉시 초기화)

클래스가 로드될 때 즉시 인스턴스를 생성합니다.

public class Singleton {
    private static final Singleton INSTANCE = new Singleton();

    // private 생성자
    private Singleton() {
    }

    public static Singleton getInstance() {
        return INSTANCE;
    }
}

장점:

  • 간단하고 구현이 쉽습니다.
  • 스레드에 안전합니다.

단점:

  • 클래스가 사용되지 않아도 인스턴스가 생성됩니다. (자원 낭비 가능)

2. Lazy Initialization (지연 초기화)

필요할 때 인스턴스를 생성합니다.

public class Singleton {
    private static Singleton instance;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

장점:

  • 클래스가 사용될 때만 인스턴스를 생성합니다.

단점:

  • 스레드 안전하지 않습니다. (멀티스레드 환경에서 동기화 필요)

3. Thread-Safe Singleton (스레드 안전한 싱글톤)

멀티스레드 환경에서 안전하게 싱글톤을 구현하려면 동기화가 필요합니다.

방법 1: Synchronized 키워드 사용

public class Singleton {
    private static Singleton instance;

    private Singleton() {
    }

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

장점:

  • 간단하고 동기화를 통해 스레드 안전성을 보장합니다.

단점:

  • 성능 저하가 발생할 수 있습니다. (동기화 오버헤드)

방법 2: Double-Checked Locking (이중 검증)

public class Singleton {
    private static volatile Singleton instance;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

장점:

  • 성능과 스레드 안전성을 모두 만족합니다.

단점:

  • 구현이 조금 복잡합니다.

4. Bill Pugh Singleton

Bill Pugh 방식은 중첩된 정적 클래스를 사용하여 싱글톤을 구현합니다.

public class Singleton {
    private Singleton() {
    }

    private static class SingletonHelper {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonHelper.INSTANCE;
    }
}

장점:

  • 스레드 안전성을 제공하면서도 성능 저하가 없습니다.
  • 클래스가 로드될 때 인스턴스를 생성하지 않으므로 메모리를 절약할 수 있습니다.

단점:

  • 초기 학습 비용이 있을 수 있습니다.

5. Enum Singleton

Enum을 사용하여 싱글톤을 구현하면 자바에서 제공하는 기본적인 스레드 안전성을 활용할 수 있습니다.

public enum Singleton {
    INSTANCE;

    public void someMethod() {
        // 메서드 구현
    }
}

장점:

  • 구현이 매우 간단합니다.
  • Serialization과 Reflection에 대해 안전합니다.

단점:

  • Enum을 사용하는 것이 어색하게 느껴질 수 있습니다.

싱글톤 패턴의 주의점

  1. Reflection 방어: Reflection을 통해 private 생성자를 호출할 수 있으므로 이를 방어해야 합니다.
  2. Serialization 문제: 직렬화된 인스턴스를 역직렬화하면 새로운 객체가 생성될 수 있습니다. 이를 방지하려면 readResolve 메서드를 구현해야 합니다.
protected Object readResolve() {
    return getInstance();
}
  1. 멀티스레드 환경: 멀티스레드 환경에서 안전한 구현 방법을 사용해야 합니다.

결론

싱글톤 패턴은 간단하면서도 강력한 디자인 패턴으로, 특정 클래스의 인스턴스가 하나만 존재해야 하는 상황에서 유용합니다. 그러나 구현 방법에 따라 성능이나 스레드 안전성에 영향을 줄 수 있으므로, 사용하려는 환경에 맞는 방법을 선택하는 것이 중요합니다.

728x90