싱글톤 패턴 (Singleton)
본문 바로가기
CS/디자인 패턴

싱글톤 패턴 (Singleton)

by IYK2h 2023. 1. 12.
728x90

싱글톤 패턴 (Singleton)

클래스의 인스턴스가 하나임을 보장하고 접근할 수 있는 전역적인 접근점을 제공하는 패턴

장점

하나의 인스턴스를 만들어 놓고 해당 인스턴스를 다른 모듈들이 공유하며 사용하기 때문에 인스턴스를 생성하는데 드는 비용이 줄어든다.

자원을 많이 잡아먹는 인스턴스가 있다면 유용하다.

단점

의존성이 높다.

-> 의존성 주입(DI, Dependency Injection)을 통해 모듈 간의 결합을 조금 더 느슨하게 만들어 해결할 수 있다.

TDD

-> 단위 테스트는 서로 독립적이어야 하며 어떤 순서로든 실행할 수 있어야 한다. 싱글톤 패턴은 테스트마다 독립적인 인스턴스를 만들기 어렵다.

싱글톤이 깨지는 경우

멀티스레딩

-> 동기화 필요

클래스 로더가 2개 이상일 때

-> 클래스 로더를 직접 지정

리플렉션, 직렬화, 역직렬화

-> enum으로 해결

// 리플렉션
Singleton singleton1 = Singleton.getInstance();

Constructor<Singleton> declaredConstructor = Singleton.class.getDeclaredConstructor();
declaredConstructor.setAccessible(true); // private 메소드 접근 가능하게 변경
Singleton singleton2 = declaredConstructor.newInstance();

System.out.println(singleton1 == singleton2); // false
// 직렬화, 역직렬화
Singleton singleton1 = Singleton.getInstance();
Singleton singleton2 = null;

try (ObjectOutput out = new ObjectOutputStream(new FileOutputStream("singleton.obj"))) { 
    out.writeObject(singleton1);
}
try (ObjectInput in = new ObjectInputStream(new FileInputStream("singleton.obj"))) { 
    singleton2 = (Singleton) in.readObject();
}

System.out.println(singleton1 == singleton2); // false

추천 구현 방법 2가지

1. SingletonHolder - Bill Pugh Singleton Implementaion (static inner class)

static inner class를 사용해서 instance를 지연 초기화(lazy initialization)하는 방법

getInstance를 호출할 때 SingletonHolder가 static 영역에 올라가면서 INSTANCE가 생성된다. (메모리 낭비 방지)

public class Singleton {
 
    private Singleton() { }
 
    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
 
    // getInstance가 호출될 때 로딩이 되기 때문에 멀티쓰레드 환경에서도 문제없다.
    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

2. enum (Joshua Bloch-Effective Java(아이탬 3)

enum Singleton {
    INSTANCE
}

단점 : 초기 생성 비용발생, 상속 불가능

참고 구현 방법

1. DCL(double checked locking)

멀티 쓰레드 환경과, 클래스 락의 최소화

public class Singleton {
 
    private Singleton() { }
 
    // Java 1.5 버전 이상부터 volatile 사용 가능
    private static volatile Singleton instance;
 
    // double checked locking
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

 

 

 

 

'CS & 개녕 정리/디자인 패턴' 카테고리의 글 목록

안녕하세요. 하루에 2시간씩 꾸준히 하자는 의미로 만든 블로그입니다. 꾸준히 활동하겠습니다. 감사합니다.

iyk2h.tistory.com

 

728x90

'CS > 디자인 패턴' 카테고리의 다른 글

팩토리 패턴(factory pattern)  (0) 2023.01.13
디자인 패턴  (0) 2023.01.11
MVC pattern  (0) 2021.07.02

댓글