티스토리 뷰
7) 델리게이트를 이용하여 콜백을 표현하라
콜백을 설명하기 위한 간단한 대화로 시작해보자.
공장장 : "기모씨, 제가 공장 둘러보는 동안 A 공정 파트 좀 민수씨가 맡아 주고 전화로 상태 보고해주세요~"
안기모 : "공장장님, 우선 A-1 공정 <제품 소재 정리> 끝냈습니다."
안기모 : "공장장님, A-2 공정 <제품 제작> 끝냈습니다."
안기모 : "공장장님, A-3 공정 <제품 마감>을 위한 기계가 고장났습니다."
공장장 : "아 그래요? 제가 설비 관리 팀에 문의 넣어 놓을게요."
잠시후
안기모 : "공장장님, A 공정 완료했습니다."
공장장은 안기모씨에게 A 공정이라는 일을 시켰고 안기모씨는 여러 차례에 걸쳐 공장장에게 일 상태를 보고했다. 공장장은 공장 여러 곳을 둘러보다가도 잠깐씩 A공정의 상태를 같이 체크해주지만 공장을 둘러보는 것을 멈추지 않는다. 안기모씨는 A 공정에서 중요한 상태를 수차례 공장장에 알리고 문제가 생기면 도움도 요청한다.
콜백은 서버가 클라이언트에게 비동기적(asynchronous)으로 피드백을 주기 위해서 주로 사용하는 방법이다. 이를 위해서 멀티스레딩 기술도 사용되고, 동기적으로 상태를 갱신하는 기법도 활용된다. 콜백은 C#에서 델리게이트를 이용하여 표현된다.
델리게이트의 다양한 활용 방법
델리게이트를 이용하면 타입 안정적인 콜백을 정의할 수 있다. 대부분의 경우에 델리게이트는 event와 함께 사용되지만 반드시 그래야 하는 것은 또 아니다.
여러 클래스가 상호 통신을 수행해야 할 때 클래스간의 결합도를 낮추기 위해서 인터페이스말고 델리게이트를 사용할 수도 있다.
델리게이트는 런타임에 통지 대상을 설정할 수 있다.
하나의 델리게이트가 여러 메서드에 대한 참조가 가능하기 때문에 다수의 클라이언트에게 통지를 보낼 수 있다.
참조 메서드는 Static 메서드일 수도 있고 인스턴스 메서드일 수도 있다.
.NET Framework 라이브러리의 델리게이트 형태
.NET Framework는 Predicate<T>, Action<>, Func<>와 같은 형태로 자주 사용하는 델리게이트를 정의해두었다.
Predicate<T> : 조건을 검사하여 bool값을 반환하는 델리게이트
Func<> : 여러 개의 매개변수를 받아 특정 타입의 단일 결과값을 반환하는 델리게이트
(Func<T, bool> = Predicate<T>
Action<> : 여러 개의 매개변수를 받지만 결과값의 타입이 void인 델리게이트
예시) LINQ : 콜백을 기반하는 List<T>의 다양한 메서드
Find() 메서드는 Predicate<int> 형식의 델리게이트를 사용해서 리스트 내에 포함된 요소에 대하여 테스트를 수행한다.
TrueForAll() 메서드 또한 비슷한 방법으로 동작하는데 각 요소를 개별적으로 테스트하되 모든 항목이 테스트를 통과할 경우에만 True를 반환한다.
ForEach() 메서드는 리스트 내의 각 요소에 대하여 델리게이트로 지정한 동작을 수행한다.
델리게이트는 런타임에 콜백을 수행하는 최고의 방법이다. 장점을 다시 살펴보자.
콜백을 사용해야 하는 클라이언트를 더단순하게 구성할 수 있다.
런타임에 콜백 함수를 구성할 수 있다.
하나의 델리게이트에 여러 개의 콜백 함수를 추가할 수 있다.
.NET 환경에서 콜백이 필요한 경우에는 반드시 델리게이트!!
솔직히 말하자면 델리게이트, 콜백이라는 개념을 아직 완벽히 숙지하지 못 했다. 대충 감 정도만 잡고 있을 뿐. 그래도 처음에는 진짜 1도 이해가 되지 않았는데 지금은 읽기는 가능한 것에 어느정도 다행이라고는 생각한다. 안 그래도 조만간 C# 기본서를 사서 다시 정독해볼 예정인데, 그 때 콜백, 델리게이트 개념을 확실히 다져야 겠다.
참거 - Effective C# <강력한 C# 코드를 구현하는 50가지 전략과 기법, 이펙티브>, 빌 와그너, 김명신, 한빛미디어
'Programming > Effective C#' 카테고리의 다른 글
[Effective C# Item 9] 박싱과 언박싱을 최소화하라 (0) | 2020.10.18 |
---|---|
[Effective C# Item 8] 이벤트 호출 시에는 null 조건 연산자(?.)를 사용하라 (0) | 2020.10.18 |
[Effective C# Item 6] nameof() 연산자를 적극 활용하라 (0) | 2020.10.18 |
[Effective C# Item 5] 문화권별로 다른 문자열을 생성하려면 FormattableString을 사용하라 (0) | 2020.10.18 |
[Effective C# Item 4] string.Format()을 보간 문자열로 대체하라 (0) | 2020.10.18 |