코드를 작성할때 순차적으로 만들어 왔는데 상대에게 거꾸로 요청할 수 있는 상황이 빈번하게 일어나는데 이러한 일을 대리자로 처리할 수 있다.
한줄로 설명하자면, 함수 자체를 인자로 넘겨주는 방법 (callback방식)이라고 생각하면 된다.
class Program
{
//대리자
delegate int OnClicked(void);
//OnClicked는 대리자니까 int와string과같은 형식으로 함수자체를 인자로 넘겨주는 형식이라고 생각한다.
//반환 :int 입력 :void
//OnClicked는 delegate 형식의 이름이다.
//UI
static void ButtonPressed(OnClicked clickedFunction //버튼이 눌렸을때 함수를 호출할 인자를 넘겨주고 싶다.)
{
//함수를 호출
clickedFunction();
}
static int TestDelegate() //실제 대리자에서 구현해야하는 부분 (로직)
{
Console.WriteLine("Hello Delegate");
return 0;
}
static int TestDelegate2()
{
Console.WriteLine("Hello Delegate 2");
return 0;
}
static void Main(string[] args)
{
//delegate ( 대리자 )
//ButtonPressed(TestDelegate); 간단히 호출하는방법도 있다.
OnClicked clicked = new OnClicked(TestDelegate);
clicked();
//대리자는 체인이 가능하다. 여러개의 함수를 동시에 넘겨줄 수 있다.
clicked += TestDelegate2;
ButtonPressed(clicked);
}
}
대리자의 치명적인 단점이 하나 존재하는데
설계적으로 볼때 위에 코드에서 Delegate로 구현한 함수를 누구나 호출 할 수 있다는게 문제이다.
위에 코드를 부분만 가져와서 설명
delegate int OnClicked(void);
//UI
static void ButtonPressed(OnClicked clickedFunction)
{
//함수를 호출
clickedFunction();
}
static void Main(string[] args)
{
OnClicked clicked = new OnClicked(TestDelegate);
clicked(); // 누구나 호출할 수 있다는 문제부분
}
위의 코드에서 만약 clickedFunction()이 굉장이 중요한 부분이고 함부로 호출되면 안되는 부분이라 할 때 메인 함수의 clicked()는 누구나 호출할 수 있기에 설계적인 문제가 생긴다고 볼 수 있다.
근데 이러한 대리자를 랩핑해줄 수 있는 Event라는 문법이 있다.
class InputManager
{
public delegate void OnInputKey();
public event OnInputKey InputKey; //외부에서만 사용가능
public void Update()
{
if (Console.KeyAvailable == false)
return;
ConsoleKeyInfo info = Console.ReadKey();
if(info.Key == ConsoleKey.A)
{
//모두한테 알려준다.
InputKey();
}
}
}
class Program
{
static void OnInputTest()
{
Console.WriteLine("Input Reveived!");
}
static void Main(string[] args)
{
InputManager inputManager = new InputManager();
inputManager.InputKey += OnInputTest; //구독신청
while (true)
{
inputManager.Update();
}
//inputManager.InputKey; 더이상 그냥 호출할 수 없다.
}
}
InputManager라는 키 입력을 받는 클래스를 만들고
A라는 키가 입력되었을 때 모두에게 알려주는 코드를 만든다고 했을 때 키를 받아 알려줘야하니
대리자로 OnInputKey를 선언하고 한번더 Event로 랩핑해준다고 생각하면 된다.
그러면 메인함수에서 호출 하려하면 호출할 수 없다.
대신 +=나 -=로 구독,구독취소를 할 수 있다.
그리고 추가로 구독자를 모집한 다음에 특정 이벤트가 발생했을 때 구독자들한테 메시지를 뿌리는 방식을 ObSERVER Pattern이라 한다.