1. 정의
Singleton pattern은 객체 지향 프로그래밍에서 매우 자주 사용되는 디자인 패턴 중 하나다. 이 패턴은 클래스의 인스턴스가 오직 하나만 생성되도록 보장하며, 이 인스턴스에 대한 전역적인 접근을 제공한다. 많은 언어와 프레임워크에서 널리 사용되는 디자인 패턴이다.
인스턴스가 오직 1개만 생성되면
1) 최초 한 번의 연산자를 통해 고정된 메모리 영역만 사용하여 객체 접근성이 용이해지고 메모리 사용을 최적화한다.
2) 인스턴스의 생성과 관리를 중앙 집중적으로 처리함으로써, 일관성 있는 동작을 보장할 수 있다.
3) 전역적인 상태를 관리하는 클래스가 필요할 때 유용하다. Ex) 데이터베이스 연결, 로그 생성, 설정 정보 등
Singleton pattern의 구현 방법은 다양하며, 대표적으로는 lazy initialization 방식을 사용한다. 이는 인스턴스가 필요할 때 생성되는 방식으로 메모리 사용을 최적화할 수 있다. 단, 동기화 문제가 발생할 수 있어 동기화 처리가 필요하다.
Singleton pattern의 특징은 두 가지가 있다.
1) 클래스의 인스턴스가 하나만 생성된다. Singleton 클래스에서 생성자를 private으로 선언하여, 클래스 외부에서 인스턴스를 생성할 수 없도록 한다. 대신 클래스 내부에 유일한 인스턴스를 생성하고, 이를 반환하는 정적 메소드를 제공한다.
2) 전연적으로 접근 가능한 인스턴스를 제공한다. Singleton 클래스에서 getInstance() 메소드를 제공하여 언제 어디서든지 Singleton 인스턴스에 접근 가능하도록 한다.
2. 문제점 & 해결방안
(1) 문제점
1) 동기화 문제
멀티스레드 환경에서의 동기화 문제가 발생할 수 있다. 여러 스레드가 동시에 Singleton 인스턴스에 접근하면, 동시에 인스턴스를 생성하는 경우가 발생할 수 있다.
2) Unit test 부적합
Singleton 클래스는 전역적으로 접근 가능한 인스턴스를 제공하기 때문에, 테스트 환경에서 동작을 제어하기 어렵다.
3) 의존성 주입 지원 X
Singleton 인스턴스는 클래스 내부에서 생성되어 외부에서 생성자를 통해 인스턴스를 전달 받을 수 없다.
(2) 해결방안
1) 동기화 문제 해결을 위해서는 인스턴스를 미리 생성하거나, lazy initialization 방식을 사용한다. 미리 생성하는 방식은 스레드 안전성을 보장하지만, 메모리 낭비를 발생시킬 수 있다. 반면, lazy initialization 방식은 인스턴스를 필요할 때 생성함으로 메모리 사용을 최적화할 수 있다.
2) Unit test를 적용할 수 있도록, 인터페이스를 사용하거나, 테스트용 Mock 객체를 생성한다. 인터페이스 사용 시, Singleton 클래스와 의존하는 객체 사이의 결합도를 낮출 수 있다.
3) 의존성 주입을 지원하려면 Singleton 클래스의 생성자에 필요한 객체를 전달받도록 변경할 수 있다. 그러면 Singleton 인스턴스를 직접 생성하지 않고, 외부에서 생성한 인스턴스를 주입할 수 있다.
'Study' 카테고리의 다른 글
#14. [OS] Starvation(기아 현상) (0) | 2023.04.23 |
---|---|
#13. [DB] 데이터베이스의 정규화(Database Normalization) (1) | 2023.04.18 |
#11. [DB] Transaction의 Isolation level (0) | 2023.03.15 |
#10. [DB] Transaction과 ACID (2) | 2023.03.14 |
#9. [CS] Context switching (0) | 2023.03.09 |