인스턴스를 단 한 개만 생성하여 사용하게 하는 디자인 패턴이다.
특정 클래스의 인스턴스를 생성하는 것을 제한하여 단 한 개의 인스턴스만 사용할 수 있게 한다.
특정 클래스의 인스턴스를 생성하는 것을 제한하기 위한 가장 빠른 방법은 생성자의 접근 제어자를 바꾸는 것이다.
생성자를 정의할 때, public 제어자로 정의하게 되는데, 접근하지 못 하도록 private로 바꾼다.
기존 생성자:
class Example {
public Example() {
//생성자입니다.
}
}
수정한 생성자:
class Example {
private Example() {
//생성자입니다.
}
}
생성자의 접근 제어자를 private로 바꾸었다면, 어떻게 유일하게 가질 수 있는 클래스 인스턴스를 생성할 수 있을까?
그 것을 클래스 내부의 static 변수로 해결한다.
접근 제어자가 private이어야 외부에서 함부로 인스턴스를 사용하거나 초기화하지 못 하게 막을 수 있다.
class Example {
private Example singletonInstance = new Example();
private Example() {
}
}
유일한 인스턴스는 생성했지만, 접근하거나 사용 할 방법이 없게 된다.
이를 static 메소드를 활용하여 접근하고 사용할 수 있게 하자.
💡 클래스 선언부에 생성 코드가 있는 것은 좋지 않을 수 있고, 호출 시 생성하는 것이 메모리 사용에 도움이 되기 때문에, 호출 시 메소드 내에서 생성할 수 있도록 코드를 수정하는 것이 좋다.class Example {
private static Example singletonInstance = null;
private Example() {
}
public static Example getSingletonInstance() {
if (singletonInstance == null) singletonInstance = new Example();
return singletonInstance;
}
}
if문을 사용하여 초기화가 되지 않았다면, 새로 생성하게 되고, null이 아니라면 Example 타입의 singletonInstance를 반환하게 된다.
static 메소드이기 때문에 외부에서 인스턴스 생성 없이 호출할 수 있으며, 이 함수를 사용하여 외부에서 유일한 객체를 접근하여 사용할 수 있게 된다.
호출 예시:
Example instance = Example.getgetSingletonInstance();
💡 위 singleton 패턴 적용 방식의 단점은 thread-safe하지 않다고 알려져 있다.
단점을 보완한 singleton 패턴은 추후에 공부하기로 한다.