posted by 방랑군 2012. 1. 19. 01:14

Singleton 패턴은 굳이 용어를 들먹이지 않아도 자연스레 사용되는 패턴 중 하나입니다.

하나의 클래스에 대하여 하나의 인스턴스만 생성되게끔 만들어주는 것인데요.

 

단순히 로그를 남기는 File 로거를 구현해보고자 합니다.

클래스 다이어그램을 보시면 이해가 빠릅니다.

 



클래스 내부에 static 인스턴스를 반환하는 메서드를 포함하고, 생성자를 private로 제한함으로써

해당 클래스의 인스턴스를 생성하는 방법을 제한할 수 있습니다.

즉, 해당 클래스의 인스턴스를 획득할 수 있는 방법은 static 인스턴스를 반환하는 메서드를 호출하는 방법 뿐이겠지요.

 

public class LogManager
{
    
private static LogManager _instance;

 

    public static LogManager Instance
    {
        
get 
        {
            
if (_instance == null)
                _instance = 
new LogManager();

            return _instance; 
        }
    }

 

    private LogManager()  // Constructor as Private
    {
        _fileStream = 
File.OpenWrite(GetExecutionFolder() + "\\Application.log");
        _streamWriter = 
new StreamWriter(_fileStream);
    }

 

    private FileStream _fileStream;
    
private StreamWriter _streamWriter;

 

    public void WriteLog(string message)
    {
        
StringBuilder formattedMessage = new StringBuilder();
        formattedMessage.AppendLine(
"Date: " + DateTime.Now.ToString());
        formattedMessage.AppendLine(
"Message: " + message);

        _streamWriter.WriteLine(formattedMessage.ToString());
        _streamWriter.Flush();
    }

 

    public string GetExecutionFolder()
    {
        
return Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
    }
}

로거를 Singleton 형태로 구현하였을 때 얻는 이점은 쉽게 떠올릴 수 있습니다.

1. 하나의 인스턴스를 돌려가며 사용하기 때문에 메모리가 절약됩니다.

2. File 접근에 대한 Locking과 그에 따르는 오버헤드를 고려하지 않아도 됩니다.

 

단점도 존재합니다.

1. 멀티-스레딩 환경에서는 약간의 오버헤드를 감수하여야 합니다. (.Net에서는 Thread Safe를 보장합니다 :D)

 

'강좌 > C#' 카테고리의 다른 글

C# 멀티코어 프로그래밍  (0) 2012.01.19
[C#] Template Method 패턴  (0) 2012.01.19
[C#] 리플렉션 Reflection  (1) 2012.01.19
[C#] 소멸자 (de-constructor, finalizer)  (0) 2012.01.18
Thread vs ThreadPool  (0) 2012.01.18
posted by 방랑군 2012. 1. 19. 00:27

실행 중에 클래스나 객체의 타입 정보를 조사하는 기능이다.


타입 정보는 보통 컴파일 중에만 사용되며 컴파일러에 의해 기계어로 바뀌고 나면 사라지는 것이 일반적이나 C#은 컴파일된 결과 코드뿐만 아니라 타입에 대한 메타 데이터를 실행 파일에 같이 기록해 놓기 때문에 실행중에도 정보를 조사할 수 있다.


이 기능을 사용하면 실행 중에 다른 모듈에 선언된 인스턴스를 생성할 수 있고 메서드를 호출할 수도 있다.

Type 클래스에서 제공되는 정보로부터 모든 멤버의 정보를 알아낼 수 있기 때문에 실행 중에 클래스 선언문을 통해 복원할 수도 있을 것이다.

 

특정 클래스나 객체의 타입 정보를 조사하고 싶을 때에는 Type 객체를 얻어야 하는데 다음의 세가지 방법으로 얻는다.
------------------------------------------------

// 런타임 시 지정된 이름으로 접근하는 방법

1) Type p = Type.GetType("Top");

 

// 클래스 타입으로 접근하는 방법

2) Type p = tyoeof("Top");

 

// 객체로 접근하는 방법

3) Type p = Top.GetType()

 

Top t = (Top)Activator.CreateInstance(p);

------------------------------------------------

 

// Top 형의 타입에 해당하는 클래스 정보를 Type 형의 객체로 얻어낸다.

// 이 객체 안에 Top 형에 관련된 모든 타입 정보가 들어있다고 보면 된다.

// CLR의 도움 없이 사용자가 직접 핸들하여 객체를 생성하는 것이 된다.

//

// 어셈블리 내에 들어있는 클래스의 타입 정보를 핸들하는 클래스를 Type 클래스라 할 수 있다.

 

  Type 클래스 : 클래스의 정보를 관리하는 클래스라 정의내릴 수 있다.

 

  다음의 예제 코드는, Type 클래스를 이용하여 특정 클래스의 정보를 출력한다.

//////////////////////////////////////////////

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Reflection;

namespace ReflectionTest1
{
    public class ReflectionTest
    {
        public int temp = 1000;
        public void PrintShow()
        { }

        static void Main(string[] args)
        {
            try
            {
                Type t = Type.GetType("ReflectionTest1.ReflectionTest");

                Console.WriteLine("기본 클래스 타입");
                Console.WriteLine(t.BaseType);

 

                Console.WriteLine("\n생성자 목록");
                ConstructorInfo[] cList = t.GetConstructors();
                foreach (ConstructorInfo c in cList)
                    Console.WriteLine(c);

 

                Console.WriteLine("\n함수 목록");
                MethodInfo[] mList = t.GetMethods();
                foreach (MethodInfo m in mList)
                    Console.WriteLine(m);

 

                Console.WriteLine("\n변수 목록");
                FieldInfo[] fList = t.GetFields();
                foreach (FieldInfo f in fList)
                    Console.WriteLine(f);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
    }
}

//////////////////////////////////////////////

 

리플렉션을 사용하지 않은 보통의 경우 우리가 작성한 프로그램은 CLR 내에서 실행되는 프로그램이다.

 

리플렉션을 사용하면 우리는 실행되는 프로그램이 아닌 실행시켜 주는 프로그램까지 만들어낼 수 있다.

 

즉, 미들웨어급 프로그램을 만들어낼 수 있다.

 

출처 : 소설같은 c#

 

## 책에는 리플렉션을 활용한 리플렉션 프로그래밍 기법이 소개되어 있습니다.

'강좌 > C#' 카테고리의 다른 글

[C#] Template Method 패턴  (0) 2012.01.19
[C#] Singleton 패턴이 적용된 File 로거  (0) 2012.01.19
[C#] 소멸자 (de-constructor, finalizer)  (0) 2012.01.18
Thread vs ThreadPool  (0) 2012.01.18
마샬링 (Marshaling)  (0) 2012.01.18