반응형
 

싱글톤 패턴: 개념과 6가지 구현 방법

소프트웨어 개발에서 **싱글톤 패턴(Singleton Pattern)**은 클래스의 인스턴스가 단 하나만 존재하도록 보장하는 설계 패턴입니다. 이 글에서는 싱글톤 패턴의 개념, 6가지 구현 방법, 그리고 자바(Java)에서 이를 활용하는 방법과 다양한 예시를 살펴보겠습니다.


싱글톤 패턴이란?

싱글톤 패턴은 특정 클래스의 인스턴스를 하나만 생성하고, 전역적으로 접근할 수 있도록 설계합니다. 주로 설정 관리, 데이터베이스 연결, 로깅 등 애플리케이션 전반에서 하나의 객체만 필요할 때 사용됩니다.

특징:
  1. 유일한 인스턴스 보장: 동일한 인스턴스를 여러 곳에서 공유.
  2. 글로벌 접근: 인스턴스에 어디서든 접근 가능.
  3. 자원 절약: 객체 생성 비용 절감.

싱글톤 패턴의 6가지 구현 방법

  1. Eager Initialization (즉시 초기화)
  2. Lazy Initialization (지연 초기화)
  3. Thread-Safe Singleton (스레드 안전)
  4. Double-Checked Locking (이중 검증 락)
  5. Bill Pugh Singleton (정적 내부 클래스)
  6. Enum Singleton (열거형)

1. Eager Initialization (즉시 초기화)

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

예제:
public class EagerSingleton {
    private static final EagerSingleton INSTANCE = new EagerSingleton();

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

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

public class Main {
    public static void main(String[] args) {
        EagerSingleton instance1 = EagerSingleton.getInstance();
        EagerSingleton instance2 = EagerSingleton.getInstance();

        System.out.println(instance1 == instance2); // true
    }
}
장점:
  • 간단하고 구현이 쉬움.
  • 스레드 안전.
단점:
  • 사용하지 않아도 인스턴스를 미리 생성하여 자원 낭비 가능.

2. Lazy Initialization (지연 초기화)

인스턴스를 처음 요청할 때 생성합니다.

예제:
public class LazySingleton {
    private static LazySingleton instance;

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

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

public class Main {
    public static void main(String[] args) {
        LazySingleton instance1 = LazySingleton.getInstance();
        LazySingleton instance2 = LazySingleton.getInstance();

        System.out.println(instance1 == instance2); // true
    }
}
장점:
  • 필요할 때만 인스턴스를 생성.
단점:
  • 멀티스레드 환경에서 안전하지 않음.

3. Thread-Safe Singleton (스레드 안전)

멀티스레드 환경에서 안전한 방식으로 싱글톤을 구현합니다.

예제:
public class ThreadSafeSingleton {
    private static ThreadSafeSingleton instance;

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

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

public class Main {
    public static void main(String[] args) {
        ThreadSafeSingleton instance1 = ThreadSafeSingleton.getInstance();
        ThreadSafeSingleton instance2 = ThreadSafeSingleton.getInstance();

        System.out.println(instance1 == instance2); // true
    }
}
장점:
  • 스레드 안전.
단점:
  • 성능 저하 가능 (synchronized 사용).

4. Double-Checked Locking (이중 검증 락)

성능 문제를 해결하기 위해 인스턴스 생성 시 한 번만 synchronized 블록을 사용합니다.

예제:
public class DoubleCheckedLockingSingleton {
    private static volatile DoubleCheckedLockingSingleton instance;

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

    public static DoubleCheckedLockingSingleton getInstance() {
        if (instance == null) {
	        synchronized (DoubleCheckedLockingSingleton.class) {
	        	if (instance == null) {
	        		instance = new DoubleCheckedLockingSingleton();
        		}
        	}
        }
        return instance;
    }
}
장점:
  • 스레드 안전.
  • 성능 최적화.

5. Bill Pugh Singleton (정적 내부 클래스)

정적 내부 클래스를 활용하여 싱글톤을 구현합니다.

예제:
public class BillPughSingleton {
    private BillPughSingleton() {
	    // private 생성자
    }

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

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

public class Main {
    public static void main(String[] args) {
        BillPughSingleton instance1 = BillPughSingleton.getInstance();
        BillPughSingleton instance2 = BillPughSingleton.getInstance();

        System.out.println(instance1 == instance2); // true
    }
}
장점:
  • 클래스 로딩 시점에 인스턴스를 생성하지 않음.
  • 스레드 안전.

6. Enum Singleton (열거형)

자바의 enum을 사용하여 싱글톤을 구현합니다. 자바에서 가장 간단하고 안전한 싱글톤 구현 방식으로 평가받습니다.

예제:
public enum EnumSingleton {
    INSTANCE;

    public void doSomething() {
	    System.out.println("싱글톤 동작 중!");
    }
}

public class Main {
    public static void main(String[] args) {
        EnumSingleton instance1 = EnumSingleton.INSTANCE;
        EnumSingleton instance2 = EnumSingleton.INSTANCE;

        System.out.println(instance1 == instance2); // true
        instance1.doSomething();
    }
}
장점:
  • 구현이 간단하고 안전함.
  • 직렬화/역직렬화 및 리플렉션 공격 방어.

싱글톤 패턴의 활용 예시

  1. 설정 관리: 애플리케이션의 전역 설정 값을 저장.
  2. 로깅: 동일한 로깅 인스턴스를 모든 클래스에서 공유.
  3. 데이터베이스 연결: 하나의 연결 인스턴스를 유지하여 자원 절약.
  4. 캐싱: 데이터를 캐싱하여 성능 향상.

마치며

싱글톤 패턴은 자바 개발에서 자주 사용되는 디자인 패턴 중 하나입니다. 6가지 구현 방법을 상황에 맞게 선택하고 활용하면 코드의 안정성과 효율성을 높일 수 있습니다. 프로젝트에서 적절히 적용해 더 나은 소프트웨어를 만들어 보세요!

 
반응형

+ Recent posts