싱글턴 패턴이란
- 인스턴스가 사용될 때 똑같은 인스턴스를 생성하는 것이 아니라, 동일 인스턴스를 사용하게!
- 메모리 낭비 방지
- 싱글톤으로 만들어진 인스턴스는 전역적으로 사용되기 때문에 다른 클래스의 인스턴스들이 데이터를 공유할 수 있다.
- 프로그램 상에서 동일한 커넥션 객체를 만드는 경우, 하나만 사용되어야 하는 객체를 만들어야 하는 경우 유용
- but!
싱글톤 인스턴스에게 많은 일을 위임하거나 너무 많은 데이터를 공유시키면 싱글톤 인스턴스와 다른 클래스 인스턴스들 간에 coupling이 많아지고 결합도가 높아져 개방폐쇄원칙에 위배
Eager initialization
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() { }
public static Singleton getInstance() {
return instance;
}
- 생성자에 private 키워드를 붙여, new 키워드를 사용할 수 없게 되므로, 다른 클래스에서 new 키워드를 사용할 수 없다. -> 인스턴스 생성 불가.
외부 클래스가 Singleton 클래스의 인스턴스를 가질 수 있는 방법은 getInstance()
메서드
를 사용하는 것
- but!
클래스가 load되는 시점에 인스턴스를 생성시킨다는 단점 (사용되지 않더라도 load된다)
Lazy initialization
public class Singleton {
private static Singleton instance;
private Singleton() { }
public static Singleton getInstance() {
if (instacne == null) {
instance = new Singleton();
}
return instance;
}
}
- 최초 사용 시점에만 인스턴스화시키기 때문에 프로그램이 메모리에 적재되는 시점에 부담이 많이 줄게 된다.
- but!
동일 시점에 getInstance() 메서드를 호출하면 인스턴스가 2번 생길 위험이 있기 때문에 프로그램이 multi thread 방식이라면 위와 같은 방식이 안전하지 않다.
Initialization on demand holder idiom
public class Singleton {
private Singleton() { }
private static class SingletonHolder {
private static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
- 클래스 안에 클래스(holder)를 두어 JVM의 Class Loader 매커니즘과 class가 로드되는 시점을 이용한 방법. thread 간 동기화 문제를 해결할 수 있다.
- 중첩 클래스 holder는
getInstance()
메서드가 호출되기 전에는 참조되지 않고, 최초로 getInstance()
메서드가 호출될 때 클래스 로더에 의해 싱클톤 객체를 생성하여 리턴.
좋은 글이네여! 한가지 질문 있습니다 Static vs Singleton 뭐가 더 낫나요?