본 내용은 Java언어로 배우는 디자인패턴 입문(한빛미디어) 책을 보면서 정리한 내용입니다.
Singleton 클래스에서는 인스턴스를 하나만 만들고, static 필드(클래스 변수)로서 singleton이 정의되어 Singleton 클래스의 인스턴스에서 초기화가 됨.
이 초기화는 Singleton 클래스를 로드할 때 한번만 실행 됨.
Singleton 클래스의 생성자는 private로 되어 있음.
이것은 Singleton 클래스 외부에서 생성자를 불러내는 것을 막음.
Singleton 클래스의 유일한 하나의 인스턴스를 얻을 메소드로서 getInstance가 있음.
유일한 하나의 인스턴스를 얻을 수 있는 메소드가 필요하며 주로 getInstance로 이름 붙임.
public class Singleton {
private static Singleton singleton = new Singleton();
private Singleton() {
System.out.println("인스턴스 생성 완료");
}
public static Singleton getInstance() {
return singleton;
}
}
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 메소드를 갖고 있음(getInstance).
이 메소드는 언제나 같은 인스턴스를 반환함.
제한을 둔다는 것은 전제가 되는 조건이 증가한다는 의미.
인스턴스가 다수 개 존재하면 인스턴스들이 상호간에 영향을 주어 생각지 못한 버그가 발생할 수 있음.
인스턴스가 하나밖에 없다고 보증되면 그 전제 조건 하에서 프로그래밍을 할 수 있음.
프로그램을 실행하고 나서 처음으로 getInstance 메소드를 호출했을 때 Singleton 클래스는 초기화됨.
그리고 이때 static 필드의 초기화가 이루어지고 단 하나의 인스턴스가 만들어짐.
예) 인스턴스가 3개만 가지고 있는 경우.
내부에 배열을 만들어 놓고, getInstance(int index)의 형태로 구현하여, index의 값의 인스턴스가 없으면 생성을 하고, 있을 때는 해당 인덱스의 인스턴스를 가져오는 식으로 구현이 가능함.
대부분 인스턴스가 하나뿐인 패턴일 때 연관됨.
public class Main extends Thread {
public static void main(String[] args) {
System.out.println ("Start. ");
new Main("A").start();
new Main("B").start();
new Main("C").start();
System.out.println("End.");
}
public void run() {
Singleton obj Singleton.getlnstance();
System.out.println(getName() + ": obj = " + obj);
}
public Main(String name) {
super(name);
}
}
위와 같은 멀티쓰레드에서 작동하는 코드일 때, 아까의 Singleton 코드를 사용하면, 인스턴스가 여러개 만들어질 수 있음.
이것을 막기 위해서는 synchronized 키워드를 붙여주어서 해결 할 수 있음.