싱글톤 패턴(Singleton Pattern) 디자인패턴(싱글톤패턴)

I. Singleton 이란?

아마 GOF의 32가지 패턴 중 가장 쉬우면서도 가장 자주 쓰이게 되며, 가장 문제가 될 소지를 가지는 패턴을 말하면 Singleton을 말할 수 있지 않을까 합니다.

먼저 Singleton 패턴의 용도는 하나의 프로그램 내에서 하나의 인스턴스만을 생성해야만 하는 상황. 예를 들어 환경설정을 관리하는 클래스나
Connection Pool, Thread Pool과 같이 풀(Pool) 형태로 관리되는 클래스의 경우 프로그램 내에서 단 하나의 인스턴스로 관리되는 것이 일반적이며, 이 때 Singleton 패턴을 적용하는 것이 일반적인 경우라고 볼수 있겠습니다. 그럼 세부적인 구현 형태를 살펴 보도록 하겠습니다.

II. Singleton 구현

Singleton 패턴의 가장 일반적인 형태는 다음과 같습니다.

singleton.bmp 

<일반적인 Singleton class diagram>

중요하게 보아야 할 곳은 생성자가 private으로 선언되어 있다는 것이죠. 이유는 간단하게도 클래스 외부에서 이 클래스를 직접 new 키워드로 생성하지 못하게 막겠다는 의미가 되겠습니다. Singleton 패턴은 설명보다는 코드로 보는 것이 훨씬 간결하므로 다음 코드를 보도록 하겠습니다.

  1. Singleton 패턴 

  2. class Singleton { 

  3. private static Singleton instance;

  4. private Singleton(){ 

  5. public static Singleton getInstance(){ 

  6. if (instance == null) 

  7. instance = new Singleton();  

  8. return instance; 

  9. }

 

   위 코드에서 파란색으로 표기된 선언부에 집중해야 합니다. Singleton 클래스의 인스턴스를 외부에서 사용하기 위해서는 항상 getInstance 메소드를 호출해야만 하도록 강제된 것을 확인하실 수 있습니다.  위와 같은 경우 getInstance가 호출될 때 객체가 생성되는데 최초 로딩 시에 객체를 생성해 두는 것이 효율적인 경우에는 다음과 같이 멤버 변수를 선언하는 곳에서 직접 생성하는 방법을 이용할 수 있습니다.

 

  1. ClassLoader에 의해 미리 인스턴스를 생성하는 방법 
  2. class Singleton { 
  3. private static Singleton instance = new Singleton(); 
  4. private Singleton(){} 
  5. public static Singleton getInstance(){ 
  6. if (instance == null) 
  7. instance = new Singleton(); 
  8. return instance; 

위의 코드에서 붉은색으로 표기된 멤버 변수 선언부를 보면 new 키워드에 의해 static으로 선언된 멤버 변수의 인스턴스를 미리 생성하는 것을 볼 수 있습니다.

다중 쓰레드 프로그래밍에 필요한 것이 아니라면 위의 코드만으로도 완성된 코드라고 볼수 있겠습니다. 미리 인스턴스를 생성할 필요가 없는 경우에는 이전의 방법을 이용하는데 그런한 방식을 lazy(게으른) 방식이라고 이야기 합니다.

다중 쓰레드 프로그래밍에서는 동기화를 이용한 적절한 수정이 필요한데 많은 커뮤니티에서 그에 따른 예제 코드가 잘 나와있습니다.

(Singleton의 다양한 형태 : http://www.anfamily.net/mcsong/70)

위의 블로그에 방문하시면 싱글톤 패턴의 다양한 종류와 그에 따른 장단점이 잘 분류되어 있습니다.

다만 좀더 자세히 내용을 들여다 보면 가장 간단한 방법이 오히려 득이 되는 경우를 찾을 수 있을 것 입니다. 다음 코드를 봐주세요.

  1. Instance의 생성은 단 한번만

  2. class Singleton{

  3. private static Singleton instance = new Singleton();

  4. private Singleton(){}

  5. public static Singleton getInstance(){

  6. return instance;

  7. }

  8. }

위의 코드의 녹색으로 표시된 부분을 봐주세요. Simple is best 라는 말 처럼 위의 코드는 Thread-safe하게 잘 만들어진 코드라고 할 수 있겠습니다.

이 클래스는 전체 라이프 타임 중에서 단 한번만 객체를 생성하고 다시는 생성하지 않습니다. 여러개의 쓰레드가 접근을 한다고 하더라도 인스턴스가 두개 이상 생성되거나 Null값을 리턴 받을 염려도 생성자가 두번 호출 되는 경우도 없죠. 

 

III. 결론

하나의 패턴은 다양한 형태로 표현되는 경우가 많습니다. 어쩔 때는 경계가 모호한 형태로 패턴이 구현되는 경우도 있지요.

이번 싱글톤 패턴은 목적과 형태가 분명한 패턴으로 항상 머리에 넣어두고 사용해야할 중요한 패턴이라고 말할 수 있습니다.

 

참고문헌

YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST