Doridori C# 강의 3) 73. 디자인 패턴 1_생성 패턴 (Singleton, Factory)
======================================================
안녕하세요 Doridori 입니다.
생활을 하면서 제법 힘든 시기가 아닌가 싶은 생각이 드는 요즘 입니다.
업무 스트레스 때문인지 속이 좋지 않아 밥을 잘 먹지 못하고 있는데 제대로 먹지 못하다 보니 몸도 허해지고 성격도 날카로워 지는 것 같고...
집도 회사도 쉽지 않네요.
이게 객년기 인가 싶은 생각도 들었는데 내용을 보니 나이도 그렇고 객년기는 아닌 것 같고 그냥 우울증이 살짝 온 것 같기도 하고 그렇습니다.
뭔가 새로운 활력을 찾을 수 있는 계기가 있어야 할 것 같은데 뭘 해야 하나 싶기도 하고, 고민을 해봐야 할 듯 합니다.
좋은 일도 있고 아닌 일도 있겠지만 다들 슬기롭게 이겨내기를 바랍니다.
감사합니다. ^^
======================================================
73. 디자인 패턴 1_생성 패턴 (Singleton, Factory)
Soruce)
교재)
지난번 도도하다에서 디자인 패턴에 대해 기본 적인 내용에 대해 이야기 해 보았습니다.
2024.09.21 - [C#/도리도리 하고 싶은거 다해] - 도도하다) 24. 디자인 패턴 (Design Pattern)
이번에는 이 디자인 패턴 중 생성 패턴에 대한 이야기를 예제와 함께 다루어 볼까 합니다.
예제를 가져 왔기 때문에 디자인 패턴 상세 내용의 경우는 원래 계획 대로 c# 강의 쪽에 업로드 할 예정 입니다.
생성 패턴 중에 싱글톤 패턴과 심플 팩토리 패턴을 가지고 왔는데 팩토리 메소드 패턴과 빌더 패턴에 대한 기본 예제도 함께 포함 시켜 놓았습니다.
처음 내용 만 보면 이해가 어려 울 수 있는데 소스코드와 함께 따라가보면 어떻게 사용이 되는지 흐름을 파악하는데 많은 도움이 되지 않을까 생각 합니다.
강의)
Source)
Main Form 호출 부분 입니다.
각 패턴들을 호출 하고 사용 하는 부분을 구현하고 있습니다. 빌더 패턴의 경우 전체 소를 받아서 확인 하시면 됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
using CreationalPatterns.Patterns;
namespace CreationalPatterns
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
#region Form Event
private void btnSingleton_Click(object sender, EventArgs e)
{
fSingleton();
}
private void btnFactory_Click(object sender, EventArgs e)
{
fFactory();
}
private void button1_Click(object sender, EventArgs e)
{
fBuilder();
}
#endregion
#region Inner Function
private void fSingleton()
{
// Singleton stest = new Singleton();
Singleton singleton1 = Singleton.GetInstance();
Singleton singleton2 = Singleton.GetInstance();
if (singleton1 == singleton2)
{
Log(enLogLevel.Info_L1, "싱글톤) 같은 인스턴스를 참조하고 있습니다.");
}
string sRet = singleton1.doCal(1);
Log(enLogLevel.Info_L1, $"singleton1) {sRet}");
sRet = singleton2.doCal(2);
Log(enLogLevel.Info_L1, $"singleton2) {sRet}");
sRet = singleton1.doCal(3);
Log(enLogLevel.Info_L1, $"singleton1) {sRet}");
sRet = singleton2.doCal(4);
Log(enLogLevel.Info_L1, $"singleton2) {sRet}");
}
private void fFactory()
{
IFactoryCreatorCal product1 = Factory.FactoryProductShape("Triangle");
string sRet = product1.AreaCal(3, 4).ToString();
Log(enLogLevel.Info_L2, $"factoryTriangle) : {sRet}");
IFactoryCreatorCal product2 = Factory.FactoryProductShape("Square");
sRet = product2.AreaCal(3, 4).ToString();
Log(enLogLevel.Info_L2, $"factorySquare) : {sRet}");
cBase product1_1 = new ConcreteProductTriangle2();
sRet = product1_1.someOp(7, 8).ToString();
Log(enLogLevel.Info_L2, $"factoryTriangle) : {sRet}");
cBase product2_1 = new ConcreteProductSquare2();
sRet = product2_1.someOp(7, 8).ToString();
Log(enLogLevel.Info_L2, $"factoryTriangle) : {sRet}");
}
/// <summary>
/// 참고
/// </summary>
private void fBuilder()
{
Director director = new Director();
IBuilder builder = new ConcreteBuilder();
// 복잡한 객체 생성
director.Construct(builder);
Product product = builder.GetResult();
product.Show();
}
#endregion
#region Log Viewer (기존 Source 재활용)
int iMaxListCount = 12;
// Log Level을 지정 할 Enum (44강 Tree View 참조)
enum enLogLevel
{
Info_L1,
Info_L2,
Info_L3,
Warning,
Error,
}
private void Log(enLogLevel eLevel, string LogDesc)
{
this.Invoke(new Action(delegate ()
{
if (lboxLog.Items.Count >= iMaxListCount)
{
lboxLog.Items.RemoveAt(iMaxListCount - 1);
}
DateTime dTime = DateTime.Now;
string LogInfo = $"{dTime:yyyy-MM-dd hh:mm:ss.fff} [{eLevel.ToString()}] {LogDesc}";
lboxLog.Items.Insert(0, LogInfo);
}));
}
private void Log(DateTime dTime, enLogLevel eLevel, string LogDesc)
{
this.Invoke(new Action(delegate ()
{
if (lboxLog.Items.Count >= iMaxListCount)
{
lboxLog.Items.RemoveAt(iMaxListCount - 1);
}
string LogInfo = $"{dTime:yyyy-MM-dd hh:mm:ss.fff} [{eLevel.ToString()}] {LogDesc}";
lboxLog.Items.Insert(0, LogInfo);
}));
}
#endregion
}
}
|
cs |
Singleton.cs)
싱글톤 패턴에 대한 예제를 다루고 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CreationalPatterns.Patterns
{
/// <summary>
/// 단 하나의 인스턴스만 생성
/// 스레드 안전성을 고려한 구현 (lock 사용)
/// </summary>
internal class Singleton
{
// 유일한 인스턴스를 저장할 정적 변수
private static Singleton instance = null;
// 인스턴스 생성을 제어하기 위한 객체
private static readonly object lockObj = new object();
// 외부에서 인스턴스를 생성하지 못하도록 private 생성자
private Singleton() { }
// 유일한 인스턴스를 반환하는 정적 메서드
public static Singleton GetInstance()
{
lock (lockObj) // 스레드 안전성 보장
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
int sumNum = 0; // 계산값을 저장 할 내부 변수
public string doCal(int num)
{
sumNum = sumNum + num;
return $"작업 결과 값 : {sumNum}";
}
}
}
|
cs |
Factory.cs)
심플 팩토리 패턴과 팩토리 메소드 패턴에 대한 예제를 다루고 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CreationalPatterns.Patterns
{
/// <summary>
/// 객체 생성 로직을 캡슐화하여 클라이언트 코드와 분리
/// 코드 확장성이 좋고, 새로운 제품 추가 시에도 기존 코드 변경 없이 가능
/// </summary>
internal class Factory
{
// Product
public static IFactoryCreatorCal FactoryProductShape(string type)
{
if (type == "Triangle")
{
return new ConcreteProductTriangle();
}
else if (type == "Square")
{
return new ConcreteProductSquare();
}
else
{
throw new ArgumentException("잘못된 타입입니다.");
}
}
}
// 제품 인터페이스
// Creator
public interface IFactoryCreatorCal
{
string AreaCal(double width, double height);
}
// 구체적인 제품 클래스 1
// ConcreteProduct
public class ConcreteProductTriangle : IFactoryCreatorCal
{
// ConcreteCreator
public string AreaCal(double width, double height)
{
double dRet = width * height / 2;
return $"작업 결과 값 삼각형의 넓이 : {dRet}";
}
}
// 구체적인 제품 클래스 2
public class ConcreteProductSquare : IFactoryCreatorCal
{
public string AreaCal(double width, double height)
{
double dRet = width * height;
return $"작업 결과 값 사각형의 넓이 : {dRet}";
}
}
#region factory Method (참고)
abstract class cBase
{
public abstract IFactoryCreatorCal fCreate();
public string someOp(double w, double h)
{
IFactoryCreatorCal ifc = fCreate();
return ifc.AreaCal(w, h);
}
}
class ConcreteProductTriangle2 : cBase
{
public override IFactoryCreatorCal fCreate()
{
return new ConcreteProductTriangle();
}
}
class ConcreteProductSquare2 : cBase
{
public override IFactoryCreatorCal fCreate()
{
return new ConcreteProductSquare();
}
}
#endregion
}
|
cs |