티스토리 뷰
1. 싱글톤 (Singleton) 이란?
Ensure a class has only one instance and provide a global point of access to it.
- 해당 클래스의 인스턴스가 하나만 생성이 되는것을 보장하고, 어디서든지 그 인스턴스에 접근이 가능하도록 만드는 패턴
- 어플리케이션이 시작될 때, 어떤 클래스가 최초 한번만 메모리를 할당하고(Static) 그 메모리에 인스턴스를 만듬
= 그 이후에 생성자 시도한다면, 최초에 생성된 객체를 리턴하도록 함 (getInstance())
= 객체가 다른 방법으로 생성되지 않도록 생성자를 Private로 구현한다.
2. 사용되는 곳
- 추상 팩토리, 빌더, 프로토타입 패턴을 구현할 때에 싱글톤을 사용할 수 있음
- 퍼사드 객체(Facade), 상태 객체(State) 는 종종 싱글톤으로 사용
- DBCP : DataBase Connection Pool), Thread Pool, 캐시, 로그 기록 객체 등
3. 구조 (UML 다이어그램)
(1) singleton private 멤버변수 선언
(2) 생성자를 private로 선언하여 외부에 노출이 되지 않도록 함
(3) 이후에 Static으로 전역에서 접근이 가능한 메소드(getInstance)를 생성해서 인스턴스를 반환
: 멤버변수에 이미 변수가 생성이 되어 있다면 해당 인스턴스를 리턴하며,
만약 인스턴스가 한번도 초기화 되지 않았다면, 생성한 후 리턴
4. 싱글톤 패턴을 사용하는 이유 - 장점
- 메모리 낭비 방지 : 한번만 new 로 인스턴스를 생성하기 때문
: 객체를 생성하게 되면 그 클래스의 인스턴스는 Heap 메모리에 올라가게 되고, 그 인스턴스를 가리키고 있는 변수는 Stack 메모리 영역에 생기게 된다. 이러한 작업 자체가 시간이 걸리는 일이며 한 객체를 여러번 new하게 되면 시간이 더욱 오래 걸리게 된다.
그래서 자주 사용되는 객체는 한번만 생성한 후, Heap에 존재하는 이 객체를 가리키도록만 만든다.
=> 즉, 객체가 생성될 때 Heap 영역에 올라가는 시간과 메모리를 줄일 수 있다.
- 전역 인스턴스 이므로, 다른 클래스의 인스턴스에서 데이터 공유 용이
- 공통된 객체를 여러개 생성하여 사용하는 상황에서 유용 : ex) DB Pool
- 그 인스턴스를 오직 '한개'만 존재하는 것을 보증할 때 사용
- 두번째 호출 시 부터는 객체 로딩시간이 줄어서 성능이 좋아짐
- 불필요한 변수들로 전역 네임스페이스를 오염시키지 않음
- 상속이 가능하여 간단하게 사용 가능
- 실행시간에 초기화 됨
: 게으른 초기화를 사용하는 것은 정적 변수와 차이가 있다 : 정적멤버변수는 정적 초기화 및 컴파일러가 변수의 초기화 순서를 보장하지 않으므로, 정적 변수끼리의 의존 불가능
5. 싱글톤 패턴의 유의점
- 멀티 스레드 기반의 어플리케이션에서 주의해야 함
객체가 아직 생성되지 않은 시점에서 동시에 생성자 호출 -> 동시에 객체 유무 체크 -> ※ 단 하나의 객체만 생성하도록 해야한다
뮤텍스, 세마포어의 기능을 지원할 경우, 싱글톤 객체 생성자의 "원자성"을 보장해야한다
클래스에 상호배제(mutual exclusion)을 사용하여, 객체가 생성되고 있음을 알려야 한다
-> 생성자에서 세마포어 등을 이용해서, 두개 이상의 스레드가 동시 접근이 불가능하도록 막을 필요가 있음
6. 싱글톤 단점
- 싱글톤을 사용하여 여러곳에서 효과적으로 호출할 수 있어서 편하지만, 결과적으로 프로그램의 Coupling을 높이게 되어 한곳에서의 변경이 다른 부분에 영향을 미치게 될 확률이 높아지게 된다.
=> 설계에 제약이 생긴다
- 초기화 시점(위치)을 제어할 수 없다
=> 멀티 쓰레드 응용 프로그램에서 명시적 초기화가 필요한 경우, 쓰레딩 문제를 예방하기 위해서 조치가 필요
7. 예제 소스
using System;
namespace DoFactory.GangOfFour.Singleton.Structural {
class MainApp {
static void Main() {
Singleton s1 = Singleton.Instance(); Singleton s2 = Singleton.Instance();
if (s1 == s2) { Console.WriteLine("Objects are the same instance"); }
// Wait for user Console.ReadKey(); } }
//싱글톤 클래스 class Singleton { private static Singleton _instance;
// 'protected' 로 생성자를 만듦 protected Singleton() { }
// 'static'으로 메서드를 생성 public static Singleton Instance() {
//다중쓰레드에서는 정상적으로 동작안하는 코드입니다. //다중 쓰레드 경우에는 동기화가 필요합니다. if (_instance == null) { _instance = new Singleton(); }
//다중 쓰레드 환경일 경우 Lock 필요 //if (_instance == null) //{ // lock(_instance) // { // _instance = new Singleton(); // } //}
return _instance; } } } http://hongjinhyeon.tistory.com/29 |
- 전역변수를 사용해서 싱글톤을 사용 안할 수도 있지만, 싱글톤은 전역변수를 사용하는데에서 발생하는 네임스페이스 충돌을 막을수가 있음
-싱글톤 패턴은 '게으르게' 인스턴스가 생성이 되므로, 객체가 자원을 많이 잡아 먹을때 유용한 생성기법
- using UnityEngine;
- using System.Collections;
- public class GameData
- {
- private static GameData instance=null;
- public static GameData Instance
- {
- get
- {
- if (instance==null)
- {
- instance = new GameData();
- }
- return instance;
- }
- }
- private GameData()
- {
- }
- public int _test; // 선언할 변수들
- }
- GameData.Instance._test;
http://vaert.tistory.com/139
http://limkydev.tistory.com/67
https://jeong-pro.tistory.com/86?category=793347
'개발 > 이론' 카테고리의 다른 글
[ASP.NET] 파일 형식 등 기본 사항 (0) | 2019.01.02 |
---|---|
[프로토콜] HTTP/HTTPS/REST (0) | 2018.12.28 |
[HTTP] 쿠키/세션/캐시의 차이점은? (3) | 2018.12.19 |
[객체지향] SOLID 원칙 (0) | 2018.12.18 |
[OSI 7계층, TCP/IP 4계층] 네트워크의 기본 계층 구조 (3) | 2018.12.17 |
- Total
- Today
- Yesterday