코드 단위의 패턴 - [켄트 벡의 구현 패턴]
클래스 단위의 패턴 - GOF의 디자인 패턴/헤드 퍼스트 디자인 패턴
아키텍쳐 패턴(패키지, 모듈, 레이어) -
마틴 파울러의 리팩토링 코드 단위의 패턴과 클래스 단위의 패턴을 커버
출처 : http://vandbt.tistory.com/38
내가 가지고 있지 않은 책 -> 켄트 벡의 구현 패턴
GoF의 디자인패턴을 C# 으로 구현했습니다.
Software Design Patterns Design patterns are recurring solutions to software design problems you find again and again in real-world application development. Design patterns are about design and interaction of objects, as well as providing a communication platform concerning elegant, reusable solutions to commonly encountered programming challenges. |
Creational Patterns | |
Abstract Factory | Creates an instance of several families of classes |
Builder | Separates object construction from its representation |
Factory Method | Creates an instance of several derived classes |
Prototype | A fully initialized instance to be copied or cloned |
Singleton | A class of which only a single instance can exist |
Structural Patterns | |
Adapter | Match interfaces of different classes |
Bridge | Separates an object’s interface from its implementation |
Composite | A tree structure of simple and composite objects |
Decorator | Add responsibilities to objects dynamically |
Façade | A single class that represents an entire subsystem |
Flyweight | A fine-grained instance used for efficient sharing |
Proxy | An object representing another object |
Behavioral Patterns | |
Chain of Resp. | A way of passing a request between a chain of objects |
Command | Encapsulate a command request as an object |
Interpreter | A way to include language elements in a program |
Iterator | Sequentially access the elements of a collection |
Mediator | Defines simplified communication between classes |
Memento | Capture and restore an object's internal state |
Observer | A way of notifying change to a number of classes |
State | Alter an object's behavior when its state changes |
Strategy | Encapsulates an algorithm inside a class |
Template Method | Defer the exact steps of an algorithm to a subclass |
Visitor | Defines a new operation to a class without change |
[출처]
private Singleton(){}
public static Singleton GetInstance() {
if (_Singleton = null)
_Singleton = new Singleton();
return _Singleton;
}
}
생성자가 private으로 외부에서는 인스턴스를 생성하지 못하게 하였고..static으로 구성된 메서드에서
인스턴스를 생성하여 리턴해주는.. 별 문제 없어보이는 방식이다..
위에 소스로 일반적인 방법으로는 문제 없이 잘 돌아간다. 하지만 멀티스레드를 이용하게 될때 문제가 크게 발생하게된다.!!!!!!
GetInstance()메서드가 한번도 실행되지 않은 상태에서.. 두개의 스레드가 동시에 GetInstance()를 호출 하게 된다면..
하나가 아닌 두개의 인스턴스가 생성되어 버리고 말것이다..
2개의 인스턴스를 하나의 인스턴스인줄 알고 사방에서 호출하여 데이타를 주고 받는다면... 엄청난 일이 버러지지 않을까...-_-;
그래서 멀티스레드를 이용하더라도 이러한 문제가 생기지 않도록 할 수 있는 방법을 알아보기로 하자.!
기본적으로 프로그램이 실행되는 순간 인스턴스를 생성!!!
public class Singleton
{
private static Singleton _Singleton = new Singleton();
private Singleton(){}
public static Singleton GetInstance()
{
return _Singleton;
}
}
하지만 위와 같은 방법에도 단점이 있다..
실행되는 순간 바로 인스턴스를 생성하였기 때문에 프로그램을 사용하면서 종료될때까지 한번도 싱글턴으로 이루어진 인스턴스를 호출 하지 않는다면 자원낭비가 될것이다.
물론 무조건 한번은 실행하게 되는 클레스라면 위와같이 구현하더라도 상관없다.
한가지 방법이 더 있다. 바로 Lock을 걸어 사용중이라면 못들어오게 하는 방법이다.
public class Singleton
{
private static Singleton _Singleton;
private Singleton(){}
public static Singleton GetInstance()
{
lock (_Singleton)
{
if (_Singleton == null)
_Singleton = new Singleton();
return _Singleton;
}
}
}
위에 lock로 묶은 부분을 실행할 때에는 _Singleton을 사용하지 못하게 하는 방법이다.
그래서 멀티스레드 방식을 코딩할때에는 lock 키워드를 사용하게 되는 것을 자주 볼 수 있는데...
대신 lock를 걸게되면 시간이 오래 걸린다는 단점이 생긴다. 그래서 lock을 거는 부분을 최소화 시켜주어야 되겠다..
public class Singleton
{
private static Singleton _Singleton;
private Singleton(){}
public static Singleton GetInstance()
{
if (_Singleton == null)
{
lock (_Singleton)
{
_Singleton = new Singleton();
}
}
return _Singleton;
}
}
이번엔 _Singleton == null 일 경우에만 lock을 걸어 보았다. 이렇게 되면 맨 처음 인스턴스를 생성할 때에만 lock을 걸어주게 되어
이후 인스턴스를 불러와서 사용하는 경우에는 아무런 속도저하 없이 사용할 수 있을 것이다.
[출처] [C#]Singleton(싱글턴 패턴)|작성자 깡아
참조 : http://www.yoda.arachsys.com/csharp/singleton.html
다음은 Windows Form을 싱글턴으로 구현한 예제
using System.Windows.Forms;
namespace SingletonSample
{
public partial class SingletonForm : Form
{
//클래스 자신을 인스턴스로 저장할 멤버
// --> 엄밀히 말하면 클래스의 유일한 인스턴스를 저장할 멤버
private volatile static SingletonForm _singletonForm;
//Dummy object for thread-safety
private static object dummy = new object();
//생성자를 감춰서 외부에서는 클래스 인스턴스를 생성할 수 없게 만듦.
private SingletonForm()
{
InitializeComponent();
}
//Property형식으로 Singleton 패턴을 구현
public static SingletonForm Instance
{
get
{
//lock은 블럭 안의 코드가 실행되는 동안 다른 쓰레드가
//이 블럭이 실행하지 못하도록 막음(다른 쓰레드는 이 블럭이
//완료될 때까지 기다림).
lock(dummy)
{
//_singletonForm이 static으로 선언되어 있으므로 이 클래스의 인스턴스는
//항상 하나만 존재하게 됨.
if (_singletonForm == null || _singletonForm.IsDisposed)
//클래스 인스턴스 생성
_singletonForm = new SingletonForm();
return _singletonForm;
}
}
}
//Method를 이용하여 Singleton 패턴을 구현
//public static SingletonForm GetInstance()
//{
// lock (dummy)
// {
// if (_singletonForm == null || _singletonForm.IsDisposed)
// {
// _singletonForm = new SingletonForm();
// }
// }
// return _singletonForm;
//}
}
static class Program
{
[STAThread]
private static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
SingletonForm form1 = SingletonForm.Instance;
form1.Text = "First SingleForm?";
form1.Show();
form1.Visible = false;
Forms.SingletonForm form2 = Forms.SingletonForm.Instance; //form1을 다시 얻어 온다.
form2.Text += " or Second SingleForm?";
form2.ShowDialog();
}
}
}
실행해보면 form2.Text가 "First SingleForm? or Second SingleForm?"이 된다. 즉, form1과 form2는 같은 form이다.
[출처] C# Singleton Pattern 구현|작성자 차돌돼라