하나의 클래스 당 하나의 인스턴스만을 생성하도록 하고, 그 인스턴스에 접근하는 단 하나의 static 메서드를 제공한다.
생성자가 여러번 호출되더라도 생성되는 객체는 하나이고 최초 생성 이후에는 생성한 객체를 리턴한다. 즉, 단 하나의 객체만 생성하고 생성된 객체를 공유해서 사용할 때 사용하는 패턴이다.
Windows에서 작업 관리자, 프린트 스풀러 같은 것이 예.
Spring에서 bean은 Singleton 객체이며 beanfactory 레지스트리에서 관리된다.
로그 프레임워크들에서 로그 객체들도 Singleton 이며 레지스트리에서 관리된다.
■ UML Class Diagram
public static MakeACaptain getCaptain() // 클래스를 제어하는 단 하나의 공용 메서드
■ Code Snippet
class MakeACaptain
{
private static MakeACaptain _captain;
//We make the constructor private to prevent the use of "new"
private MakeACaptain(){ }
// public static synchronized MakeACaptain getCaptain()
/* public static MakeACaptain getCaptain()
{
// Lazy initialization
if (_captain == null)
{ _captain = new MakeACaptain();
System.out.println("New Captain selected for our team");
}
else
{
System.out.print("You already have a Captain for your team.");
System.out.println("Send him for the toss.");
}
return _captain;
}*/
//Bill Pugh solution
private static class SingletonHelper {
private static final MakeACaptain _captain = new MakeACaptain();
}
public static MakeACaptain getCaptain()
{
return SingletonHelper._captain;
}
}
class SingletonPatternEx
{
public static void main(String[] args)
{
System.out.println("***Singleton Pattern Demo***\n");
System.out.println("Trying to make a captain for our team");
MakeACaptain c1 = MakeACaptain.getCaptain();
System.out.println("Trying to make another captain for our team");
MakeACaptain c2 = MakeACaptain.getCaptain();
if (c1 == c2)
{
System.out.println("c1 and c2 are same instance");
}
}
}
√ 실행 결과
■ 정리
1) Lazy initialization / Eager initialization
2) "Lazy initialization"일 때 getCaptain() 메서드가 호출될 때까지 싱글톤 인스턴스가 생성되지 않는다. 쓰레드로 부터 안전하지 않다. 해결 방안이 2가지가 있다.
(i) "synchronized" keyword 사용
(ii) "Eager initialization" 사용, 위 코드에서 Bill Pugh solution 에 해당
3) Singleton 객체를 관리하는 registry를 두어 관리할 수 있다. 레지스트리도 Singleton 이어야 한다.
※ 참고 자료
1) 『Java Design Patterns A Tour of 23 Gang of Four Design Patterns in Java』 (Apress, 2016)
2) https://en.wikipedia.org/wiki/Singleton_pattern
3) https://en.wikipedia.org/wiki/Lazy_initialization
'DEV' 카테고리의 다른 글
GitLab - 프로젝트 삭제 (0) | 2021.12.06 |
---|---|
Design Patterns - 4. Adapter Pattern (0) | 2021.10.24 |
Design Patterns - 2. Factory Method Pattern (0) | 2021.10.06 |
Design Patterns - 1. 디자인 패턴이란 (0) | 2021.10.06 |
Scouter - 설치 (0) | 2021.09.28 |