-
싱글톤 패턴(Singleton Pattern)디자인 패턴 2021. 10. 28. 20:58
💡 싱글톤 패턴이란?
GOF의 디자인 패턴중 '생성' 패턴에 속하는 패턴으로, 클래스에서 오직 '한 개'의 인스턴스만 인스턴스 화 할 수 있도록 규제하는 디자인 패턴
📗 싱글톤 패턴의 장점
- 클래스가 오직 한 개의 인스턴스만 가지고 있다고 확신 할 수 있다.
- 인스턴스 수를 제한 할 수 있다.
- 전역 변수에 액세스 함으로써 손쉽게 접근 할 수 있다.
📖 함께 쓰일 수 있는 패턴들
- Abstract pattern, Factory Method, Builder, Prototype
- State pattern, Facade Pattern
📖 전역변수보다 싱글톤 패턴이 나은 점
- 불필요한 변수로 Global namespace를 훼손하지 않는다.
- 지연 할당과 초기화를 지원함으로써 사용하든 안하든 리소스를 소모하는 전역변수와 달리 싱글턴 패턴은 효율적으로 자원 활용이 가능하다.
⚠️ 싱글톤 패턴의 단점
- 싱글톤 패턴은 안티 패턴에 속한다. 안티패턴이란 프로그램을 만들 때 비효율적이고 역효과가 나타날 수 있는 패턴을 말한다.
- 싱글톤 패턴은 주로 global하게 선언되는데, 이는 프로그램의 결합도를 증가시켜 유닛 테스트를 하기 힘들게하고, 싱글톤 객체에 의존하는 객체가 불필요한 제약을 따르게 한다.
- 싱글톤 패턴을 사용하면, 싱글톤 패턴을 적용한 객체는, 객체를 오직 '하나'만 생성해야 하는 규약과 자신이 원래 하던 일 두가지를 하게 되므로 SRP(Single responsible Principle)도 위반한다.
🚀 구현
일반적으로 싱글턴은 클래스의 모든 '생성자'를 private으로 선언하고, 생성된 객체를 참조할 수 있는 변수를 리턴하는 static 메소드를 사용하는 방식으로 구현된다.
class SingletonTest { @Test void singletonTest() { SingletonObject singletonObject1 = SingletonObject.getInstance(); SingletonObject singletonObject2 = SingletonObject.getInstance(); System.out.println(singletonObject1 == singletonObject2); } } class SingletonObject { private static SingletonObjectinstance; private SingletonObject() {} public static SingletonObject getInstance() { if(instance== null) { instance= new SingletonObject(); } return instance; } }
output 멀티 스레드 환경에서 Race Condition을 막기 위해서 다음과 같이 구현 할 수도 있다.
class SingletonTest { @Test void singletonTest() { SingletonObject singletonObject1 = SingletonObject.getInstance(); SingletonObject singletonObject2 = SingletonObject.getInstance(); System.out.println(singletonObject1 == singletonObject2); } } class SingletonObject { private static volatile SingletonObject instance; private SingletonObject(){}; public static SingletonObject getInstance() { if(instance == null) { synchronized (SingletonObject.class) { if(instance == null) { instance = new SingletonObject(); } } } return instance; } }
output2 위의 코드에서 'volatile'과 'synchronized '키워드가 어색해서 검색해봤다.
volatile은 변수의 값을 '캐시'가 아닌 메인 메모리에 저장하라는 것이고 synchronized 키워드는 멀티 스레드 환경에서 race condition을 막기 위해 사용하는 것으로, 한 스레드가 synchronized 메소드에 들어가면 'lock'을 걸어 다른 스레드가 들어오지 못하게 하는 메소드라고 한다. 둘 다 멀티스레드 환경에서 읽기/쓰기를 할 경우 Race Condition을 방지하기 위해 사용하는 메소드인듯하다.
'디자인 패턴' 카테고리의 다른 글
Decorator Pattern (0) 2022.02.08 Observer Pattern (0) 2022.02.03 Strategy Pattern (0) 2022.02.02 Facade Pattern (0) 2021.10.27 디자인 패턴 개요 (0) 2021.01.06