이번엔 Delegate 의 장점을 느낄수 있는 예제를 하나 살펴 봅니다.
Delegate 의 여러 장점 중 메서드 간접호출을 통한 동일한 방식으로의 호출을 가능케 하는 측면의 데모입니다.
이 접근법은 MOC에 소개되어 있는 데모입니다.
일단 아래의 시나리오를 가장합니다.
가상 시나리오 >>
펌프를 제조하는 회사가 여러군데 있다. 각 제조사마다 펌프를 시작하는 명령이 다르다.
어떤 제조사(Pump1)는 펌프를 시작하기 위해서 Start 명령을 사용한다.
또 다른 제조사(Pump2)는 펌프를 시작하기 위해서 Go 명령을 사용한다.
문제는 이 펌프를 모두 모아서 사용하는 사용자이다.
이 사용자(PumpManager)는 제조사 마다 시작 명령이 달라서 펌프를 시작하는 시점에 어떤 제조사의 펌프인지를 확인하고 상황에 맞게 명령을 내려야 한다.
사용자(PumpManager)는 펌프 제조사를 신경쓰지 않고 동일한 방법으로 모든 펌프를 시작하게 하고 싶다(요구사항)
=======================델리게이트를 사용하지 않은 코드 ===================
1. 펌프 제조사 코드
public class Pump1{
public void Start()
{
Console.WriteLine("Pump1 - 시작되었습니다");
}
}
public class Pump2{
public void Go()
{
Console.WriteLine("Pump2 - 시작되었습니다");
}
}
2. 펌프 사용자 코드
public class PumpManager{
private ArrayList al = new ArrayList();
public void Add(object o)
{
al.Add(o);
}
public void AllStart()
{
foreach(Object o in al)
{
if(o is Pump1) //만일 제조사가 Pump1 이면..
{
((Pump1)o).Start();
}
else if(o is Pump2) //만일 제조사가 Pump2 이면..
{
((Pump2)o).Go();
}
}
}
}
==================델리게이트를 사용해서 요구사항을 만족시키는 코드 =============
1. 펌프 제조사 코드
- 위와 동일
2. 펌프 사용자 코드
public delegate void StartPumpCallBack(); //펌프 시작을 간접 호출할 Deleate 선언
public class PumpManagerUsingDelegate{
private ArrayList al = new ArrayList();
public void Add(StartPumpCallBack callBack) // Delegate 변수를 매개변수 받는다
{
al.Add(callBack);
}
public void AllStart()
{
foreach(StartPumpCallBack scb in al)
{
scb(); // 펌프의 시작을 Delegate 로 한다. (제조사에 상관없이 동일한 방법으로 펌프를 시작할 수 있다)
}
}
}
=========================== 메인 코드 ===================================
public static void Main(){
Pump1 p1 = new Pump1();
Pump2 p2 = new Pump2();
#region Delegate 사용하지 않는 경우
PumpManager pm = new Demo.PumpManager();
pm.Add(new Pump1());
pm.Add(new Pump2());
#endregion
#region Delegate 사용하는 경우
PumpManagerUsingDelegate pm = new PumpManagerUsingDelegate();
pm.Add(new StartPumpCallBack(p1.Start));
pm.Add(new StartPumpCallBack(p2.Go));
#endregion
pm.AllStart();
}