본문 바로가기

DEV

Design Patterns - 3. Singleton Pattern

 

 

하나의 클래스 당 하나의 인스턴스만을 생성하도록 하고, 그 인스턴스에 접근하는 단 하나의 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