💡
싱글톤 패턴은 해당 클래스의 인스턴스가 하나만 만들어지고, 어디서든지 그 인스턴스에 접근할 수 있도록 하기 위한 패턴입니다.
구현 원리
public class Singleton {
//1
private static Singleton uniqueInstance;
//2
private Singleton() {}
//3
public static Singleton getInstance() {
if ( uniqueInstance == null ) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
Singleton 클래스의 유일한 인스턴스를 저장하기 위한 정적 변수입니다.
생성자를 private으로 선언했기 때문에 Singleton에서만 클래스의 인스턴스를 만들 수 있습니다.
getInstance() 메소드에서는 클래스의 인스턴스를 만들어서 리턴해줍니다.
uniqueInstance가 null이면 아직 인스턴스가 생성되지 않았다는 것을 의미합니다.
아직 인스턴스가 만들어지지 않았다면 private으로 선언된 생성자를 이용해서 Single 객체를 만든 다음 uniqueInstance에 그 객체를 대입합니다. 이렇게 하면 인스턴스가 필요한 상황이 닥치기 전에는 아예 인스턴스를 생성하지 않게 됩니다. 이런 방법을 "게으른 인스턴스 생성(lazy instantiatioin)"이라고 부릅니다.
문제점
(1) 인스턴스를 필요할 때 생성하지 말고, 처음부터 만들어 버립니다.
public class Singleton {
//1
private static Singleton uniqueInstance = new Singleton()
//2
private Singleton() {}
//3
public static Singleton getInstance() {
return uniqueInstance;
}
}
(2) getInstance()를 동기화시켜줍니다.
public class Singleton {
private static Singleton uniqueInstance;
private Singleton() {}
//1
public static **synchronized** Singleton getInstance() {
if ( uniqueInstance == null ) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
(3)DCL(Double-Checing Locking)을 써서 getInstance()에서 동기화되는 부분을 줄입니다.
public class Singleton {
//1
private static volatile Singleton uniqueInstance;
private Singleton() {}
public static Singleton getInstance() {
//2
if ( uniqueInstance == null ) {
//3
synchronized (Singleton.class) {
if (uniqueInstance == null) {
//4
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
public class Singleton {
//1
private static let shared = Singleton()
//2
private init() {}
//3
public static func getInstance() -> Singleton {
return shared
}
public func toString() {
print("Singleton")
}
}
Singleton.getInstance().toString()
---result---
Singleton