반응형

C# 싱글톤 패턴 상속용 클래스

알게된 배경

싱글톤 패턴은 비교적 자주 사용되는 패턴이고, 멀티 스레드 프로그램을 작성할 경우 서로 상성이 안좋기 때문에 크리티컬 섹션에 대해서 뮤텍스(C#에서는 락)을 잡아줘야 한다. 문제는 이러한 패턴은 매번 반복이 되기 때문에 부모 클래스로서 작성을 해놓고, 상속받아서 기능을 구현하는 것이 여러모로 편리하다고 생각이 들기 때문에 찾아보니 해당 패턴이 있었다.

 그래서 메모겸 샘플 코드를 남긴다


부모 싱글톤

예시)

namespace Single
{
    public class Singleton<T> where T : class, new()
    {
        protected static object _instanceLock = new object();
        protected static volatile T _instance;
        public static T Instance
        {
            get
            {
                lock(_instanceLock)
                {
                    if(null == _instance)
                         _instance = new T();
                }
                return _instance;
            }
        }

    }
}



자식 싱글톤

예시)

namespace Single
{
    class MyClass : Singleton<MyClass>
    {
        // contents
        public void Print()
        {
            Console.WriteLine("Hello Singleton?");
        }
    }
}



참고자료



반응형

'C#' 카테고리의 다른 글

C# : 닷넷에서 Broadcast UDP를 보내기(1)  (0) 2018.01.29
C# : const vs readonly  (0) 2017.10.25
C# 싱글톤 패턴 : 동적 싱글톤  (0) 2017.09.04
C# Socket : 고정 구조체 만들기  (0) 2017.07.11
C# WinForm : 문자 픽셀 측정  (0) 2017.07.06
반응형

C# 싱글톤 패턴 : 동적 싱글톤

사용 목적

 하나만 있어야 하는 경우 사용되는 패턴이다. 보통 매니져 형태로 사용되는 경우에 사용된다. 간단하면서 의외로 자주 사용되는 패턴이기도 하다.

 하지만 최근에 멀티 쓰래딩을 구현할 경우 주의가 필요한 패턴이다. 보통 뮤텍스(크리티컬 섹션)와 같은 lock 기능을 통해서 동시에 접근하는 것을 막기도 하는데, 이런일이 잦을 수록 성능 향상을 저해 한다는 점도 있다.


싱글톤을 위한 기본 상식

 싱글톤(Singleton)이라는 단어에서 알 수 있듯이 하나만 존재하는 객체를 의미한다. 그래서 클래스라는 틀로 찍힌 인스턴스(실제 객체)는 하나만 존재 해야 한다.


 이 처럼 하나만 갖게 되어야 하는 조건을 충족 시키기 위해서 다음 조건들을 충족 해야 한다

 1. 생성자를 외부에서 접근되어서는 안된다(하나만 있어야 하기 때문)

 2. 인스턴스(실제 객체)는 하나만 있어야 한다.


 특히 1번의 조건을 충족하기 위해서 대부분 클래스를 지원하는 언어에서는 생성자를 private 혹은 protected 로 정의하여 외부에서 접근을 못하도록 막는 패턴을 갖게 된다.

 2번의 조건을 충족시키기 위해서는 내부에 인스턴스를 갖고 있되 접근이 가능하도록 해야 한다. 따라서 이를 위해 static으로 선언을 하게 된다. 이렇게 선언된 변수 혹은 객체는 해당 클래스를 통해서만 접근이 가능하게 된다. 그와 동시에 글로벌 영역에 객체가 존재하게 된다.

 그리고 마지막으로 싱글톤을 사용할 수 있도록 Instance 메서드를 만든다. C++의 경우 GetInstance()로 선언하는것이 관용적이지만, C#에서는 프로퍼티 기능이 있기 때문에 Get 관용구를 생략하는 경우가 있다.


구현 방법

동적 싱글톤 패턴 이기 때문에 인스턴스를 요청할때 없는 경우 생성해서 인스턴스를 반환하게 구현하면 된다.

예시)

using System;
public class Singleton
{
    private static Singleton _instance;
    private Singleton() {}
    public static Singleton Instance
    {
        get
        {
            if(_instance == null)
            {
                _instance = new Singleton();
            }
            return _instance;
        }
    }
}




위는 정석적인 방법이고 편의상 ? 연산을 이용하여 한줄로 선언할 수 있다. 이러한 방법은 코드를 간결하게 하지만, lock을 이용한 크리티컬 섹션을 설정할 수 없는 단점이 있다.

예시)

using System;
public class Singleton
{
    private static Singleton _instance;
    private Singleton() {}
    public static Singleton Instance
    {
        get
        {
            return (null == _instance) ? _instance = new Singleton() : _instance;
        }
    }
}




참조 자료

MSDN 싱글톤 패턴 문서



반응형
반응형

C++ 패턴 : 동적 싱글턴(Dynamic Singleton)

정리하게 된 배경

 은근히 자주 사용되지만, 가끔 기억이 안나서 잘 못 작성한 코드의 오류를 한참 고민을 했기 때문에 후에 있을 시간을 절약하기 위해 기록을 한다.


싱글턴 패턴

 영문으로는 Singleton이라 하기 때문에 싱글톤이라 표기 한곳도 의외로 많지만, 위키백과에서는 싱글턴으로 표기를 하기 때문에 여기서는 싱글턴으로 표기를 하였다. 싱글턴 패턴도 여러 종류가 있지만, 실용적으로 자주 사용되는 동적 싱글턴 패턴에 대해서 소스코드를 적는다.


 싱글턴 패턴은 이름에서도 알 수 있 듯이 하나만 있다는 의미를 내포하고 있다. 즉, 실질적인 객체는 오직 하나이다. 싱글턴 객체를 사용하기 위해서는 싱글턴 내부에 선언되어 있는 인스턴스객체에 접근해서 사용이 가능하다. C/C++에서는 포인터의 개념을 들어 설명을 하면 이해가 쉽지만(물론 포인터를 이해했다는 전제하에) 포인터가 없는 다른 언어에서는 종종 인스턴스 참조와 인스턴스 생성간 혼란이 있는 듯하다.

 

 논리(이론)적 구성은 단하나의 객체 혹은 인스턴스가 존재해야 하며, 추가로 선언을 못하게 해야 한다. 여기서 동적 싱글톤의 경우 프로그램 시작과 관계없이 싱글턴의 인스턴스를 받아오려는 순간 생성이 되어 생성시점이 동적인 특징이 있다.


소스코드


// Singleton.hpp
#include <iostream>

class Singleton
{
private:
    Singleton(void);
    ~Singleton(void);
    static Singleton* _instance;
public:
    static Singleton* getInstance(void);
    void print(void);
};


// Singleton.cpp
#include "Singletion.hpp"

using namespace std;

Singleton* Singleton::_instance = nullptr;

Singleton* Singleton::getInstance(void)
{
    if(nullptr == _instance)
        _instance = new Singleton;
    return _instance;
}

void Singleton::print(void)
{
    cout << "singletion!" << endl;
}


// main.cpp
#include "Singleton.hpp"

Singleton* ins = Singleton::getInstance();
ins->print();
// or
Singleton::getInstance()->print();


주의할 점

 파일을 hpp에서 getInstance()를 정의할 경우에는 상관이 없지만, cpp에서 정의를 할 경우 static 키워드가 앞에 있어서는 안된다. 만약 사용한다면 문법적인 오류로 에러 메시지를 확인하게 된다.


참고자료

경험




반응형

+ Recent posts