싱글톤 패턴
싱글톤 패턴이란 어플리케이션이 시작될 때, 최초 한 번만 메모리를 할당하고 해당 메모리에 인스턴스를 만들어 사용하는 패턴이다. 즉, 인스턴스를 1개만 생성하여 인스턴스가 필요할 때 기존의 인스턴스를 활용하는 것이다.
싱글톤 패턴은 주로 공통된 객체를 여러 개 생성해서 사용해야 하는 상황에 사용된다. 예를 들어 커넥션 풀이나 스레드 풀, 캐시, 로그 기록 객체 등 인스턴스가 1개만 존재하는 것을 보증하고 싶을 때 사용한다.
싱글톤 패턴 장점
싱글톤 패턴은 다음과 같은 장점이 있다.
- 객체를 한 번만 생성하므로 메모리 낭비를 방지할 수 있다.
- 생성된 인스턴스는 다른 클래스의 인스턴스들이 데이터를 공유하는 것이 가능하다.
싱글톤 패턴 단점
싱글톤 패턴은 다음과 같은 단점이 있다.
- 다른 클래스들 간의 결합도가 높아져 개방-폐쇄 원칙에 위배된다.
- 유지보수가 힘들고 테스트를 진행하기 어려운 문제점이 있다.
- 동기화를 신경 써야 한다.
싱글톤 생성 방법
Lazy Initialization (게으른 초기화)
Lazy Initialization 방법은 private static으로 인스턴스 변수를 만든 뒤 private 생성자로 외부에서 생성을 막고, synchronized를 이용해 동기화를 하는 방식이다. 하지만 synchronized는 큰 성능 저하를 발생시키므로 권장하지 않는다.
public class ThreadSafe_Lazy_Initialization {
private static ThreadSafe_Lazy_Initialization instance;
private ThreadSafe_Lazy_Initialization() {}
public static synchronized ThreadSafe_Lazy_Initialization getInstance() {
if (instance == null) {
instance = new ThreadSafe_Lazy_Initialization();
}
return instance;
}
}
Lazy Initialization + Double-checked Locking
Lazy Initialization 방법과는 달리 인스턴스의 존재 여부를 확인한 다음 조건문에서 synchronized를 통해 동기화를 하는 방법이다. 처음 생성 이후에는 synchronized를 실행하지 않기 때문에 성능 저하가 완화된다.
public class ThreadSafe_Lazy_Initialization {
private volatile static ThreadSafe_Lazy_Initialization instance;
private ThreadSafe_Lazy_Initialization() {}
public static ThreadSafe_Lazy_Initialization getInstance() {
if (instance == null) {
synchronized (ThreadSafe_Lazy_Initialization.class) {
if (instance == null) {
instance = new ThreadSafe_Lazy_Initialization();
}
}
}
return instance;
}
}
Initialization on demand holder idiom (holder에 의한 초기화)
클래스 안에 클래스(holder)를 두어 JVM의 클래스 로더 메커니즘과 클래스가 로드되는 시점을 이용하는 방법이다. 동기화를 사용하지 않는 이유는 개발자가 직접 동기화 문제에 대한 코드를 작성하면서 회피하려고 하면 프로그램 구조가 그만큼 복잡해지고 비용 문제가 발생할 수 있기 때문이다.
public class Something {
private Something() {}
private static class LazyHolder {
public static final Something INSTANCE = new Something();
}
public static Something getInstance() {
return LazyHolder.INSTANCE;
}
}
Reference
'객체지향' 카테고리의 다른 글
| [객체지향] 디자인 패턴(3) - 팩토리 메서드 패턴 (0) | 2022.05.02 |
|---|---|
| [객체지향] 디자인 패턴(2) - 템플릿 메서드 패턴 (0) | 2022.05.01 |
| [객체지향] 디자인 패턴 (0) | 2022.04.29 |
| [객체지향] SOLID(5) - DIP(의존관계 역전 원칙) (0) | 2022.03.01 |
| [객체지향] SOLID(4) - ISP(인터페이스 분리 원칙) (0) | 2022.03.01 |