[DesignPattern] 싱글턴 패턴

싱글턴 패턴


프로그램을 실행할 때 보통은 많은 인스턴스가 생성된다. 예를 들어 문자열을 표시하는 java.lang.String 클래스의 인스턴스는 문자열 1개에 대해서 1개가 생성되기 때문에 문자열이 1000개 등장하는 프로그램이라면, 1000개의 인스턴스가 만들어진다.

그러나 클래스의 인스턴스가 단 하나만 필요한 경우도 있다. 그것은 시스템 안에서 1개밖에 존재하지 않는 것을 프로그램으로 표현하고 싶을 때이다.

즉, 지정한 클래스의 인스턴스 절대로 1개 밖에 존재하는 않는 것을 보증하고 싶을 때 사용한다. Singleton이란 요소를 1개 밖에 가지고 있지 않은 집합을 의미한다.



Sington 클래스에서는 인스턴스를 1개 밖에 만들 수 없으며, sington은 static 필드로서 Singleton 클래스의 인스턴스에서 초기화된다. 이 초기화는 Sington 클래스를 로드할 때 1회만 실행된다.

Sington 클래스의 생성자는 private로 되어 있다. 이것은 Sington 클래스 외부에서 생성자의 호출을 금지하기 위해서이다.

Singleton 클래스의 유일한 인스턴스를 얻는 메서드로서 getInstance가 준비되어 있다. 예제 프로그램에서는 메서드의 이름을 getInstance로 했지만, 반드시 이 이름일 필요는 없다. 그러나 유일한 인스턴스를 얻을 메서드는 필요하다.


public class Singleton {

private static Singleton singleton = null;

// 외부에서는 new Singleton()를 이용하여 생성자를 호출할 수 없다.

private Singleton(){

System.out.println("인스턴스를 생성하였습니다.");

}


// getInstance 메서드는 singleton 인스턴스가 이미 생성되어 있는지를 검사한다.

// 만약 처음 호출되어 아직 인스턴스가 생성되지 않은 상황이라면 생성자를 호출해 인스턴스를 생성한다.

// 이렇게 생성된 인스턴스는 정적 변수 singleton에 의해 참조가 된다.

// 만약 인스턴스가 생성되었다면 singleton 변수에서 참조하는 인스턴스를 반환한다.

public static Singleton getInstance(){

if(singleton == null){

singleton = new Singleton();

}

return singleton;

}

}

이 코드에서 주의 깊게 살펴봐야 할 점은 getInstance 메서드와 singleton 변수가 static 타입으로 선언되었다는 점이다.

이와 같이 static으로 선언된 메서드나 변수를 각각 정적 메서드, 정적 변수라고 한다.

정적 메서드나 정적 변수는 이들이 구체적인 인스턴스에 속하는 영역이 아니고 클래스 자체에 속한다는 의미이다. 또한 클래스의 인스턴스가 생성될 때마다 생성되는 것이 아니라 딱 한 번만 생성되며 클래스의 인스턴스가 생성되기 전에 초기화된다. 그래서 정적 메서드, 정적 변수는 클래스에서 생성된 모든 인스턴스들에게 공유된다. 따라서 클래스의 인스턴스를 통하지 않고서도 메서드를 실행할 수 있고 변수를 참조할 수 있다.

우리의 목적은 단 하나의 객체만 생성해 어디에서든지 참조할 수 있게 하는 것으로 처음에 객체를 만들려면 getInstance 메서드가 정적 메서드로 선언되어 있어야 한다.


public class Main {

public static void main(String[] args){

System.out.println("Start");

Singleton obj1 = Singleton.getInstance();

Singleton obj2 = Singleton.getInstance();

if(obj1 == obj2){

System.out.println("obj1과 obj2는 같은 인스턴스 입니다.");

} else {

System.out.println("obj1과 obj2는 다른 인스턴스 입니다.");

}

System.out.println("End");

}

}

실행결과)

Start

인스턴스를 생성하였습니다.

obj1과 obj2는 같은 인스턴스 입니다.

End


Singleton 패턴에는 Singleton의 역할만이 존재한다. Singleton 역할은 유일한 인스턴스을 얻기 위한 static 메서드를 가지고 있다. 이 메서드는 언제나 동일한 인스턴스를 반환한다.

Singleton 패턴에서는 인스턴스의 수를 제한하고 있다. 일부러 제한적인 프로그래밍을 하는 이유는 제한을 한다는 것은 전제가 되는 조건을 늘린다는 의미이다.

복수의 인스턴스가 존재하면 인스턴스들이 서로 영향을 미치고, 뜻하지 않은 버그가 발생할 가능성이 있다. 그러나 인스턴스가 1개 밖에 없다라는 보증이 있다면 그 전제조건 아래에서 프로그래밍을 할 수 있다.


cf.) 유일한 인스턴스는 언제 생성되는가?

예제 프로그램의 실행결과 'Start'를 표지하고 나서 '인스턴스를 생성했습니다.'라고 표시하고 있다. 프로그램의 실행 개시 후 최초로 getInstance 메서드를 호출했을 때 Sington 클래스는 초기화된다. 그리고 이 때 static 필드의 초기화가 이루어지고 유일한 인스턴스가 만들어진다.