'designpattern' 태그의 글 목록 :: iopeni - Think of C#

'designpattern'에 해당되는 글 1건

  1. 2013.11.26 C# 으로 구현 하는 Singleton Pattern

싱글톤 패턴의 의미는 프로젝트 전역에 걸쳐 객체를 단 하나만 생성하겠다는 의미 입니다.


예전 모 프로젝트 진행 도중 어떤 선임 개발자가 이 Singleton 패턴을 남발 하여 아주 곤란한 상황에 직면했던 적이 있는 그런 모델이기는 하나 시기 적절 하게 사용하게 되면 정말 유용한 패턴 입니다.


일단 이 Singleton Pattern을 이해하기 위하여 이 패턴의 용도를 알아야 겠습니다.


싱글톤 패턴의 용도는 쉽게 이야기 한다면  "공유 데이터의 동기화"에 해당하는 문제를 풀어 나가는 방법 입니다.


다시 말하여. 

A와 B라는 객체가 동일한 temp라는 프로퍼티를 가지고 있다고 할 때, 둘의 데이타는 언제나 같은 값으로 동기화 되어야 한다면, A.temp가 변경 될 때 B.temp도 변경 하여야 하고 B.temp가 변경 될 때 A.temp도 변경 되어야 한다는 조건이 성립합니다.


이것은 프로그래밍을 할 때 피해야 하는 요소 중 한가지 순환 참조의 조건에 해당 합니다.


당연히 순환 참조가 성립 되면, 객체는 각각 객체가 가진 프로퍼티에 대입되는 값을 동기화 하기 위하여 무한 루프에 빠지게 될 것이며, 이것을 해결 하기 위하여 우리는 또 인다이렉션이라는 설계를 하게 되겠죠


역시 모든 소프트웨어 공학의 정답은 인다이렉션 입니다.


리팩토링을 설명 하면서 잠깐 데이터와 상태의 전달에 대하여 언급한 적이 있는데. 역시나 같은 문제를 놓고 고민 하게 되는 것입니다.


싱글톤 패턴의 또 다른 용도로 DB 컨넥션에 해당하는 예를 들 수 있습니다. DB는 하나의 컨넥션이 맺어질 때마다 메모리를 할당 하게 되고 하나의 어플리케이션이 다수의 컨넥션을 맺게 되면 하나의 PC는 더 많은 DB 컨넥션을 맺게 될겻이고, 이렇게 되면 대규모 사이트 일 수록 DB서버는 어마 어마한 부하를 받게 될 겁니다.


위와 같은 문제로 3 Tier를 구성 하겠지만, 2 Tier의 상황에서도 하나의 어플리케이션이 단 하나의 컨넥션만을 유지 할 수 있다면 DB쪽 부하를 상당히 줄여 줄 수 있을 것입니다. 물론 미들티어를 가지고 있는 3 Tier의 상황에서도 클라이언트가 컨넥션을 한개만 유지해 준다는 것은 미들티어의 부하를 줄여 주는 방법이기도 합니다. 이렇게 보든 저렇게 보든 부하를 줄이기 위하여 다수의 컨넥션이라는 문제를 방치하는 것은 상당히 위험해 보입니다.


이런 문제로 하나의 컨넥션을 유지하는 명시적인 방법으로 싱글톤 패턴을 활용 하기도 합니다.


물론 비지니스 성격에 따라 하나의 어플리케이션은 다수의 컨넥션을 요구 하기도 합니다. 이런 문제를 잘 파악하여, 싱글톤 패턴을 활용 할 수 있다면 비교적 좋은 성능을 가질 수 있을 것입니다. 어떻게 보면 정답 처럼 보이기도 합니다.


이 컨넥션 문제를 놓고 또 한가지 고민 해야 할 사항이 있습니다.


하나의 어플리케이션은 OS로 부터 메모리를 할당 받으면서 임계 영역이라는 것으로 메모리 보호를 받게 됩니다. DLL 제작과 같은 방법으로 Data Access Layer를 Singleton Pattern으로 구성한다고 하여도 이 임계 영역이라는 문제로 인하여 하나의 어플리케이션 과 다른 어플리케이션은 객체를 공유 할 수 없는 문제가 발생 합니다. 예전 이런 문제를 해결 하기 위하여 DCOM과 같은 기술들이 나온 것이기도 합니다.


이것의 의미는 아무리 DAL을 잘 구성 한다고 하여도 각각의 어플리케이션마다 컨넥션을 맺게 된다는 것이고 하나의 PC는 다수의 컨넥션을 맺게 됩니다. 이유는 간단 합니다. 메모리 보호 문제로 각각의 어플리케이션이 가지고 있는 메모리 어드레스를 두 어플리케이션이 공유 할 수 없기 때문입니다.


.Net 환경에서 이것을 좀 쉽게 피해 갈 수 있는 방법이 있습니다. Component Model을 활용하면 쉽게 해결 할 수 있습니다. DCOM의 확장판은 Component Model이기 때문입니다.


이쯤 적으면 어느정도 초보 단계를 벗어난 개발자분이시라면.... 아 Remoting 또는 WCF를 활용하면 되겠구나 하실 껍니다. 맞습니다. Remoting, WCF 등등이 답입니다.


참고 MSDN : http://msdn.microsoft.com/ko-kr/library/vstudio/72x4h507(v=vs.100).aspx


을 확인 하시면 Remoting 은 호환성을 유지하기 위하여 아직 사용되고 있으나, 새로운 개발에는 WCF를 사용할 것을 권장 하고 있습니다. 


싱글톤 패턴을 설명 하려고 하다가 너무 멀리 와 버렸네요.


이 처럼 객체를 하나만 사용하겠다는 것은 많은 것들을 이야기 합니다. 또 다른 관점으로는 메모리와 데이타를 어떻게 사용하느냐의 문제 이기 때문에 프로그래밍의 발전 역사와도 맞물려 돌아 가겠죠.


어플리케이션이 동작하는 상태를 만약 싱글톤 패턴으로 관리 하게 된다면 어떨 까요? 현 상황에서 어떤 로직으로 분기 해야 하는지 아니면 현 상황에서 어떤 화면을 나타내야 하는지 등에 해당하는 내용을 싱글톤 패턴으로 관리 하게 된다면 좀 쉽지 않을까요? 여기 저기서 상태를 체크 하는 .. 또는 정리 되지 않은 또는 여기 저기 산재 되어 있는 비지니스 프로세스 때문에 고민하는 우는 좀 줄일 수 있지 않을까요? 거의 완벽에 가까운 인다이렉션 설계로 종속성 관리를 완벽하게 하지 못한다면 말이죠...


다음과 같은 C#  코드로 싱글톤 패턴을 구현 할 수 있습니다. 차암 쉽죠잉~~~ ^^

class SingletonTest
    {
        static void Main(string[] args)
        {
            var singleton = Singleton.getObject();
            getObject.SaySomething();

            Console.ReadKey();
        }
    }

    public class Singleton
    {
        private static Singleton _SingleObject;

        private Singleton() { }

        public static Singleton getObject()
        {
            if (_SingleObject== null)
            {
                _SingleObject= new Singleton();
            }
            return _SingleObject;
        }

        public void SaySomething()
        {
            Console.WriteLine("Test Singleton");
        }
    }

여기서 OOP를 잘 이해 하지 못하는 분들을 위해 몇가지 부가 설명을 적습니다.


규칙

1. 싱글톤 오브젝트는 오로지 하나여야 하기 때문에 static으로 제한 합니다.

2. 인스턴스는 static에 접근 할 수 있으나 static은 인스턴스에 접근 할 수 없습니다.


위 두가지 규칙이 Singleton패턴의 모든 규칙이라고 할 수 있습니다. 그런데 한가지 좀 심하게 고민 해 봐야 할 문제가 있습니다. 우연히도 완벽하게 동일한 시스템 클럭에 완벽하게 동일하게 두개의 클라이언트가 동시에 싱글톤 객체를 생성하려고 한다면 어떻게 하여야 할까요? 한번 고민해 보시길 바랍니다.


Posted by 프로그래머란 카페인을 코드로 변환하는 기계다
,