싱글톤 패턴 (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
'CS > 디자인 패턴' 카테고리의 다른 글
팩토리 패턴(factory pattern) (0) | 2023.01.13 |
---|---|
디자인 패턴 (0) | 2023.01.11 |
MVC pattern (0) | 2021.07.02 |
댓글