[Design Pattern] 싱글톤

2016. 2. 15. 22:56프로그래밍/Design Patterns

728x90
728x90

제일 처음으로 사용해 본 디자인 패턴이다. 예전에 지인이 해놓은 피티를 보니

꽤 내용을 잘 정리해놔서 옮겨 본다.

싱글톤이야 지겹게 써봤지만 화룡점정을 찍는 정리.


출처 : https://c.aitl.in/ 홈피 관리자 머리 속에서 정리된 것을 정리한 피피티


싱글톤 패턴

전략

클래스가 유일한 인스턴스를 갖고, 그 인스턴스는 전역에서 액세스 할 수 있도록 한다.

전역변수다!


손해

멀티 스레딩에 시간 지연이 생긴다.

전역에서 액세스 하기때문에 문제가 발생하면 모든 코드를 둘러봐야 한다.

기능 단위 테스트나 변경을 위해 관련 구조만 뽑아내기 어렵다.


이득

단 하나의 인스턴스만 갖도록 강제한다.

특정 인스턴스에 어디든 접근하여 자원을 사용할 수 있다. 전역변수다!

다른 클래스의 공통 기능부를 통합해 관리할 수 있다.


Basic Singleton

설명

생성자를 private으로 만든다.

일반적으로 getInstance과 같은 이름의 static method를 호출하여

private으로 생성한 instance의 레퍼런스나 포인터를 반환한다.


단점

무조건 메모리의 할당이 이루어진다.

다른 전역 개체의 생성자에서 참조가 가능하다는 보장이 없을 수도 있다.



Dynamic Singleton

설명

최초로 getInstance()할 때 동적할당을 이용한다.


단점

해제를 위해 stdlib의 atexit나 전역 객체의 소멸자를 사용한다.

friend를 사용하는 경우 하나하나 추가해 주어야 한다.



Local Static Singleton

설명

getInstance가 호출되는 시점에 Lazy Instantiation 된다.

자동으로 프로그램 종료 시 소멸된다.


단점

다른 전역 객체의 소멸자에서 싱글톤 객체를 소멸 시킬 경우 이중 해제를 시도한다. #define SAFE_RELEASE ... 스멜이?




Phoenix Singleton

설명

한 클래스의 소멸자가 이미 소멸시켰을 경우 다른 클래스의 소멸자는 소멸시킬 수 없다.

atexit으로 프로세스 종료 시 destroy를 수행.


이거 단점 어따 빼먹음?




멀티 스레딩 문제

nullcheck를 하고 새 인스턴스를 얻는 과정에서 인스턴스를 얻으려는 다른 시도가 있을 수 있다.

local static을 이용하는 경우 C11은 동시 진입 시 한쪽이 초기화를 마치도록 대기하므로 문제될 것이 없다.



해결1

Vista 이후 출시된 VS에서 volatile object에 대한 read/write는 acquire/release semantics를 가진다.

그러하다고 한다. 


컴파일 된 후

쓰기전에 수행하는 것은 쓰기 전에, 읽은 뒤에 수행하는 것은 읽은 뒤에 수행됨을 보장한다.




해결2

unique_lock은 소멸자 호출 시 해제되므로 중복으로 인스턴스를 만드는 일은 없다.

어떤 방법으로 해결하든 getInstance의 호출을 최소화하는 것이 좋다. 추천은 1회!




기타(Logger)

파일 하나에 쓰기 핸들을 하나만 열 수 있다.

여러 스레드에서 사용하는 경우 locking를 통해 접근한다.





728x90
반응형

'프로그래밍 > Design Patterns' 카테고리의 다른 글

[Design Pattern] 팩토리 패턴  (2) 2016.01.30
디자인 패턴 연관도  (1) 2015.07.08
중재자 패턴  (2) 2015.05.04
싱글톤 사용하기  (2) 2015.04.21
[Design Pattern] 옵저버 패턴 개요  (0) 2015.04.18
디자인 패턴, 싱글톤, 상태패턴  (2) 2015.04.15