Search

Singleton 패턴

패턴
생성

정의

특정 클래스의 인스턴스가 오직 하나만 존재하도록 보장하고, 이에 대한 전역 접근점을 제공하는 생성 디자인 패턴
전체 시스템에서 공유해야 하는 리소스나 서비스에 대한 단일 접근점을 제공

특징

하나의 객체 : 시스템 전체에서 단 하나의 객체만 존재
전역 접근 : 어디서든 객체에 접근 가능
유일한 참조 : 객체에 대한 참조는 하나만 존재
지연 생성 : 객체는 필요할 때만 생성

주요 구성 요소

1.
Singleton 클래스
private static 필드를 사용하여 객체를 하나만 생성
public static 메서드를 통해 객체에 대한 유일한 참조를 제공
생성자를 private으로 선언하여 클래스 외부에서 객체를 직접 생성하지 못하도록 합니다.
2.
getInstance() 메서드
Singleton 객체를 얻기 위한 public static 메서드입니다.
객체가 생성되지 않았다면 생성하고, 이미 생성된 객체라면 기존 객체를 반환
3.
클래스 로딩
Singleton 클래스가 로딩될 때 객체가 생성될 수 있습니다.
Eager Initialization 방식에서 사용
4.
동기화
다중 쓰레드 환경에서 안전하게 사용하기 위해 getInstance() 메서드를 동기화해야 한다.
Lazy Initialization 방식에서 사용

작동방식

1.
Client는 Singleton 클래스의 getInstance() 메서드를 호출하여 객체를 얻는다.
2.
getInstance() 메서드는 객체가 생성되었는지 확인
3.
객체가 생성되지 않았다면 private 생성자를 호출하여 객체를 생성
4.
생성된 객체 또는 기존 객체를 Client에게 반환

장점

메모리 효율성 : 객체를 하나만 생성하기 때문에 메모리를 효율적으로 사용할 수 있습니다.
일관성 유지 : 시스템 전체에서 객체의 상태가 일관되게 유지
글로벌 접근 : 어디서든 객체에 쉽게 접근할 수 있다.
코드 간결화 : 객체 생성 과정을 캡슐화하여 코드를 간결하게 만들 수 있다.

단점

테스트 어려움 : 객체를 직접 생성하지 못하기 때문에 테스트하기 어려울 수 있다.
유연성 감소 : 객체 생성 방식을 변경하기 어렵다.
결합도 증가 : 객체에 대한 의존도가 높아져 코드의 유지 보수가 어려워질 수 있다.
지연 생성 문제 : 객체 생성이 지연되면 성능 저하가 발생할 수 있다.

사용 예시

설정 관리 : 시스템 설정 정보를 저장하는 객체
로그 관리 : 로그 기록을 관리하는 객체
캐싱 : 데이터를 캐싱하는 객체

사용법

1. Singleton 클래스 정의

private static 필드를 사용하여 객체를 하나만 생성
public static 메서드를 통해 객체에 대한 유일한 참조를 제공
생성자를 priate으로 선언하여 클래스 외부에서 객체를 직접 생성하지 못하도록 한다.
public class Singleton { private static final Singleton instance = new Singleton(); private Singleton() { } public static Singleton getInstance() { return instance; } }
Java
복사

2. Client 코드 작성

Singleton 클래스의 getInstance() 메서드를 호출하여 객체를 얻는다.
객체를 직접 생성하지 않는다.
public class Client { public static void main(String[] args) { Singleton singleton1 = Singleton.getInstance(); Singleton singleton2 = Singleton.getInstance(); System.out.println(singleton1 == singleton2); // true } }
Java
복사

Singleton 패턴의 종류와 그에 따른 사용법

Eager Initilization

클래스 로딩 시점에 객체를 생성
가장 간단한 방법이지만, 객체가 실제로 사용되지 않더라도 생성되므로 메모리 낭비가 발생할 수 있다.
public class Singleton { private static final Singleton instance = new Singleton(); private Singleton() { } public static Singleton getInstance() { return instance; } }
Java
복사

Lazy Initialization

객체가 필요할 때만 생성
메모리 효율적이지만, 객체 생성 시점에 동기화가 필요하여 성능 저하가 발생
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; } }
Java
복사