싱글톤 패턴(Singleton Pattern)은 소프트웨어 디자인 패턴 중 하나로, 클래스의 인스턴스를 하나만 생성하여 전역적으로 접근할 수 있도록 하는 패턴입니다. 이 패턴은 애플리케이션 내에서 어떤 클래스가 딱 하나의 객체만 필요하고, 그 객체를 어디서든 접근할 수 있어야 할 때 사용됩니다.
싱글톤 패턴의 주요 개념
- 유일한 인스턴스:
- 싱글톤 패턴은 특정 클래스의 인스턴스를 하나만 생성하고, 그 인스턴스를 전역적으로 접근할 수 있도록 보장합니다. 이 유일한 인스턴스는 프로그램이 실행되는 동안 공유됩니다.
- 전역 접근:
- 싱글톤 객체는 전역적으로 접근 가능하기 때문에, 어디서든 같은 인스턴스를 사용할 수 있습니다. 이를 통해 전역 상태나 설정 정보를 관리하는 데 유용합니다.
- 인스턴스 생성의 제어:
- 클래스 외부에서 직접 인스턴스를 생성하지 못하도록, 생성자를
private
으로 설정합니다. 인스턴스는 클래스 내부에서 관리되며, 필요한 경우에만 생성됩니다.
싱글톤 패턴의 구조
- Private 생성자:
- 클래스의 생성자는 외부에서 호출할 수 없도록
private
으로 선언됩니다. 이를 통해 외부에서 직접 객체를 생성하는 것을 방지합니다.
- Static 인스턴스 변수:
- 클래스 내부에 유일한 인스턴스를 가리키는
static
변수를 선언합니다. 이 변수는 클래스가 처음 로드될 때 메모리에 할당됩니다.
- Static 메서드:
- 외부에서 인스턴스에 접근할 수 있도록
static
메서드를 제공합니다. 이 메서드는 인스턴스가 존재하지 않으면 생성하고, 이미 존재하면 기존 인스턴스를 반환합니다.
싱글톤 패턴의 예시 (Java)
public class Singleton {
// 유일한 인스턴스를 저장할 static 변수
private static Singleton instance;
// 생성자는 private으로 외부에서 접근 불가
private Singleton() {
// 생성자 로직
}
// 인스턴스를 반환하는 static 메서드
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
싱글톤 패턴의 장점
- 전역적인 접근:
- 프로그램 어디에서든지 동일한 인스턴스를 사용할 수 있습니다. 전역 상태 관리에 유리합니다.
- 메모리 절약:
- 객체를 하나만 생성하기 때문에 불필요한 메모리 낭비를 줄일 수 있습니다.
- 인스턴스 제어:
- 객체 생성의 과정을 제어할 수 있습니다. 예를 들어, 인스턴스를 처음 사용할 때만 생성되도록 할 수 있습니다.
싱글톤 패턴의 단점
- 테스트의 어려움:
- 전역적인 상태를 가지므로, 단위 테스트를 할 때 의존성 주입(Dependency Injection) 방식과 충돌할 수 있습니다. 이는 테스트의 복잡성을 증가시킵니다.
- 멀티스레드 환경에서의 문제:
- 싱글톤 패턴은 멀티스레드 환경에서 동시 접근 시 문제를 일으킬 수 있습니다. 동기화(synchronization)를 사용하여 이를 해결할 수 있지만, 성능 저하를 초래할 수 있습니다.
- 클래스 간 결합도 증가:
- 싱글톤 패턴을 사용하면 클래스 간의 결합도가 증가할 수 있어, 유지보수가 어려워질 수 있습니다.
싱글톤 패턴의 변형
- 이른 초기화 (Eager Initialization):
- 클래스가 로드될 때 싱글톤 인스턴스를 미리 생성하는 방식입니다. 인스턴스 생성 비용이 낮거나, 인스턴스가 항상 사용될 때 유리합니다.
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() { }
public static Singleton getInstance() {
return instance;
}
}
- 느린 초기화 (Lazy Initialization):
- 인스턴스가 처음 필요할 때 생성하는 방식으로, 위의 예시가 이에 해당합니다. 인스턴스가 필요 없을 때는 메모리를 절약할 수 있지만, 멀티스레드 환경에서 주의가 필요합니다.
- 더블 체크 락킹 (Double-Checked Locking):
- 멀티스레드 환경에서 안전하게 싱글톤 인스턴스를 생성하기 위해 사용하는 방식입니다. 인스턴스가
null
인지 두 번 확인한 후 동기화 블록을 사용하여 생성합니다.
public class Singleton {
private static volatile Singleton instance;
private Singleton() { }
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
싱글톤 패턴은 특정 클래스의 인스턴스가 하나만 존재해야 할 때, 그리고 전역적으로 접근이 필요할 때 매우 유용한 패턴입니다. 하지만 사용 시에는 단점과 주의사항을 고려하여 신중하게 적용해야 합니다.

1. 싱클톤 패턴 연습 예제 및 해설
App
package ex04;
/**
*
* Animal 생성 (abstract)
* 타입 일치(다형성) = 쥐(동물), 호랑이(동물)
* 문지기한테 DIP만 지켜주면 됨
*/
public class App {
public static void main(String[] args) {
Doorman d1 = Doorman.instance;
Doorman d2 = Doorman.instance; // new 두번 하는 거 막기 (싱클톤 패턴)
System.out.println(d1.hashCode());
System.out.println(d2.hashCode());
}
}
- 싱글톤 패턴을 사용하여 ‘Doorman’ 클래스의 인스턴스를 하나만 생성합니다.
- ‘d1’ 과 ‘d2’는 동일한 ‘Doorman’ 인스턴스를 참조하며, 이를 ‘hasCode()’ 메소드를 통해 동일한지 확인하다.
- 싱클톤 패턴은 클래스의 인스턴스를 전역적으로 하나만 유지하고자 할 때 사용됩니다.
Doorman
package ex04;
/**
* 문지기한테 DIP만 지켜줘라는 뜻은
* 하나만 지키게 하라 즉 Animal이라는 부모에 속한 쥐, 호랑이들을
* App인 큰 틀에서 책임지게 만들어라는 뜻!
*
*
*/
public class Doorman {
//staic박스에는 doorman이 나왔고
public static Doorman instance = new Doorman();
//메소드 하나 만들기
// public static Doorman getInstance() {
// return doorman;
// }
private Doorman(){}
// 쥐 출입금지
//heap에는 쫓아내만 떠있다.
public void 쫒아내(Animal m) {
System.out.println(m.getName()+"쫒아내");
}
}
- 싱클톤 패턴을 사용하여 ‘Doorman’ 클래스의 유일한 인스턴스를 ‘instance’ 라는 정적 변수로 선언했다.
- ‘private’ 생성자를 사용하여 외부에서 인스턴스를 생성하지 못 하도록 하고, 인스턴스를 클래스 내부에서만 생성할 수 있게 한다.
- DIP원칙을 지키며, ‘Doorman’ 클래스는 ‘Animal’이라는 추상화된 타입을 사용하여 다양한 동물 객체를 처리합니다.
Share article