안녕하세요 오늘은 싱글톤 패턴에 대해 알아 볼 것입니다. 디자인 패턴을 공부하셨던 분이라면 아주 친숙한 디자인 패턴 중에 하나인데요.
흔히 "싱글톤 패턴이 뭐에요?" 라고 물으면 대게는 "1개의 인스턴스를 사용하는 디자인패턴이요." 라고 답합니다.
맞는 말이긴 하지만 뭔가 아쉬운 답변이죠? 이 부분에 대해 조금 자세히 알아봅시다.
보통 프로그램을 실행하게 되면 많은 인스턴스가 생성되는데요. Java로 예를 들어 문자열을 표시하는 java.lang.String 클래스의 인스턴스는 생성된 1개의 문자열 당 1개의 인스턴스가 생성되게 됩니다. 예를 들어 1000개의 문자열이 생성된다 했을 때 10000개의 인스턴스가 만들어지게 돼요.
그런데 클래스의 인스턴스가 딱 하나만 필요한 경우가 있어요. 보통 시스템 안에서 1개 밖에 존재하지 않는 것을 프로그램으로 표현할 때가 그 예 인데요.
컴퓨터 자체를 표현한 클래스라던지, 현재의 시스템 설정을 표현한 클래스라던지, 윈도우 시스템을 표현한 클래스등이 그 예가 됩니다.
물론! 개발자가
new ExamClass();
가 1번만 실행되도록 개발한다면 위의 클래스는 1개만 생성될 것인데요.
위처럼 개발자가 주의해서 1번만 생성되게 하는 것이 아니라
- 지정한 클래스의 인스턴스가 절대로 1개 밖에 존재 하지 않는 것을 보증 하고 싶을 때
- 인스턴스가 1개밖에 존재하지 않는 것을 프로그램 상에서 표현하고 싶을 때
라면 개발자가 주의 한다고 하더라도 위의 상황을 지키기 쉬울까요?
이렇게 인스턴스가 한 개 밖에 존재하지 않는 것을 보증해주는 패턴을 싱글톤 패턴이라 부릅니다.
요소를 1개 밖에 가지고 있지 않은 집합이라는 의미를 가지고 있는데 인스턴스가 한 개 밖에 없기 때문에 이와 같은 이름이 붙었습니다.
이제 예제 프로그램을 작성해봅시다!
간단하게 2개의 메소드를 호출하여 그 메소드가 같은 인스턴스를 사용하고 있는지 확인하는 프로그램을 작성해보죠.
Singleton 클래스는 1개의 인스턴스만 존재하는 클래스입니다.
생성자인 Singleton의 앞부분에 -가 붙어 있는 이유는 private인 것을 명시하기 위함입니다. 그리고 메소드인 GetInstance에 밑줄이 그어져 있는 이유는 static 메소드(클래스 메소드)이기 때문입니다. 자세한 부분은 여기를 확인하세요.
먼저 Singleton 클래스를 작성해봅시다!
package bami;
public class Singleton {
private static Singleton singleton = new Singleton();
private Singleton() {
System.out.println("1개의 인스턴스를 생성합니다.");
}
public static Singleton GetInstance() {
return singleton;
}
}
앞서 말했듯이 Singleton 클래스는 1개의 인스턴스만 존재하는 클래스이기 때문에 인스턴스를 1개 밖에 만들 수 없고, singleton은 static 클래스 변수로 Sington 클래스의 인스턴스에서 초기화 됩니다. 이 초기화는 Sington 클래스를 로드할 때 1회만 실행되죠.
Singleton 클래스의 생성자는 private로 되어 있는데 Singleton 클래스 외부에서 생성자의 호출을 금지하기 위해 private로 했는데요.
예를 들어
new Singleton();
의 코드가 이 클래스의 외부가 있더라도 컴파일 시에는 에러가 발생하게 됩니다.
물론 처음부터 개발자가 주의해서 new하지 않도록 한다면 private로 사용하지 않아도 되지만 그렇게 되면 싱글톤 패턴이 존재하는 이유가 없죠.
위에도 설명했듯이 인스턴스가 한 개 밖에 존재하지 않는 것을 보증해주는 패턴입니다. 그래서 이 것을 보증 해주기 위해 생성자를 private로 해둘 필요가 있죠.
이 클래스에서는 동작의 상태를 확인하기 위해 생성자 안에서 인스턴스를 생성하였다는 메세지를 출력하고 있습니다.
그 다음 Main 클래스를 작성해 볼 것인데요. Singleton 클래스를 이용하는 클래스입니다.
package bami;
public class Main {
public static void main(String[] args) {
Singleton singleton1 = Singleton.GetInstance();
Singleton singleton2 = Singleton.GetInstance();
if (singleton1 == singleton2) {
System.out.println("같은 인스턴스 입니다.");
}
}
}
여기에서는 singleton 클래스의 GetInstance 메소드를 이용해 Singleton의 인스턴스를 얻고 있어요.
GetInstance 메소드는 두 번 호출되고 있고, 반환값은 각각 singleton1과 singleton2에 대입하여 같은 인스턴스가 얻어지고 있는지의 여부를 검사하고 있어요.
참고로 인스턴스가 생성되는 시점은 '1개의 인스턴스를 생성합니다.'라고 출력하고 있는데 프로그램의 실행 후 최초로 GetInstance() 메소드를 호출 했을 때 Singleton 클래스는 초기화되고, static 필드의 초기화가 이루어지고 유일한 인스턴스가 생성됩니다.
결과는 위와 같습니다.
여기에서 Singleton의 역할은 유일한 인스턴스를 얻기 위한 static 메소드를 가지고 있다는 점입니다. 이 메소드는 언제나 동일한 인스턴스를 반환하는데요. Singleton 패턴에서는 이 Singleton의 역할만이 존재한다는 점 기억하세요!
그리고 싱글톤 패턴에서는 인스턴스의 수를 1개로 제한하고 있어요. 왜 이런 제한적인 개발을 하는 것일까요?
제한을 한다는 의미는 전제가 되는 조건을 늘린다는 의미인데요. 복수의 인스턴스가 존재한다면 인스턴스들이 서로 영향을 미치게 되고, 그로 인해 의도하지 않았던 버그들이 생길 가능성이 높아지게 돼요.
하지만 인스턴스가 1개 밖에 없게 된다는 보증이 있다면 그 전제조건 아래에서 개발 할 수 있게 되는 것이죠.
참고 : Java 언어로 배우는 디자인 패턴 입문
'프로그래밍(Basic) > 디자인 패턴(Java)' 카테고리의 다른 글
[바미] Builder 패턴에 대해 알아봅시다. (0) | 2021.10.25 |
---|---|
[바미] Prototype 패턴에 대해 알아봅시다. (0) | 2021.10.04 |
[바미] Factory Method에 대해 알아봅시다. (0) | 2021.09.21 |
[바미] 템플릿 메소드(Template Method) 패턴에 대해 알아봅시다. (0) | 2021.09.15 |
[바미] Adapter 패턴에 대해 알아봅시다. (0) | 2021.08.24 |