728x90
반응형
By 백기선.코딩으로 학습하는 GoF의 디자인 패턴
Singleton
1. 개념 및 구현 방법
2. 패턴 구현 깨트리는 방법
3. 안전하고 단순하게 구현하는 방법
4. 자바와 스프링에서 찾아보는 패턴
Singleton 패턴
인스턴스를 오직 한 개만 제공하는 클래스
- 시스템 런타임, 환경 세팅에 대한 정보 등 인스턴스가 어려개 일 때 문제가 발생할 수 있는 경우에,
오직 인스턴스 한 개만 만들어 제공하는 클래스가 필요하다.
아래와 같이 인스턴스를 생성한다면 settings1과 settings2는 서로 다른 객체가 된다.
하지만 환경 세팅과 같이 인스턴스가 오직 한 개만 생성되어야 할 때 싱글톤을 활용한다.
public class singleton {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, IOException, ClassNotFoundException {
Settings settings1 = new Settings();
Settings settings2 = new Settings();
System.out.println(settings1 == settings2); // False
}
}
패턴 구현 방법
1. private 생성자에 static 메소드
- 멀티스레드 환경에서는 인스턴스의 유일성이 유지되지 않을 수 있는 단점이 있다.
private static Settings instance;
private Settings() { }
public static Settings getInstance(){
if (instance==null){
instance = new Settings();
}
return instance;
}
public class singleton {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, IOException, ClassNotFoundException {
Settings settings1 = Settings.getInstance();
Settings settings2 = Settings.getInstance();
System.out.println(settings1 == settings2); // True
}
}
2. synchronized(동기화)를 사용해 멀티스레드 환경에 안전하게 만드는 방법
- class의 인스턴스에 대한 lock(락)을 사용하는 메커니즘
private static Settings instance;
private Settings() { }
public static synchronized Settings getInstance(){
if (instance==null){
instance = new Settings();
}
return instance;
}
3. 이른 초기화(eager initialization)을 사용하는 방법
- 사용하지 않는 객체를 미리 만드는 경우가 생길 수 있다는 단점이 있다.
private static Settings INSTANCE = new Settings();
public static Settings getInstance(){
return INSTANCE;
}
4. double checked locking으로 효율적인 동기화 블럭 생성
- synchronized를 내부에서 사용함으로써 중복 locking 체크를 한다.
public static Settings getInstance(){
if (instance == null) {
synchronized (Settings.class){
if(instance == null){
instance = new Settings();
}
}
}
return instance;
}
5. static inner 클래스 사용
- 이 방법은 static final을 썼는 데도 왜 지연 초기화(lazy initialization)으로 볼 수 있는가?
-> getInstance()가 호출될 때 inner class가 로딩이 되고, 그 때 static fianl을 생성하기 때문에 지연 초기화가 가능하며 단순하다.
private Settings() { }
// inner class 설정
private static class SettingsHolder {
private static final Settings INSTANCE = new Settings();
}
public static Settings getInstance(){
return SettingsHolder.INSTANCE;
}
728x90
반응형
'Design Patterns > 생성(Creational)' 카테고리의 다른 글
[FactoryMethod]장점과 단점 (0) | 2022.05.20 |
---|---|
[Singleton]4. 자바와 스프링에서 찾아보는 패턴 (0) | 2022.04.08 |
[Singleton]3. 안전하고 단순하게 구현하는 방법 (0) | 2022.04.07 |
[Singleton]2. 패턴 구현 깨트리는 방법 (0) | 2022.04.05 |
[디자인패턴]Strategy Pattern01_추상클래스와 인터페이스 (2) | 2021.01.28 |