C#
Action
Callback
역시 설명은 예시로~
여러가지 경우에 쓰이지만
아래와 같은 예를 들어보겠습니다.
Main Class 가 있습니다.
여기에서 Watcher 라는 클래스의 객체를 만들어서 파일 모니터링을 한다고 합니다.
특정 경로의 폴더에 어떤 파일이 생기거나 삭제되거나하면 알림을 주는건데요.
프로세스는 아래와 같습니다.
1. 프로그램이 실행되면 Watcher 를 띄워서 모니터링을 시작합니다.
이때 Main Class 에서는 본인이 할일을 합니다.
2. Watcher 가 모니터링 중에 파일 생성을 감지했습니다.
Watcher는 Main 을 호출해서 Main 에서 해당 작업을 처리해야 합니다.
이럴때 코드를 어떻게 만드시겠습니까?
제가 주니어였을 땐 아래와 같이 코딩했습니다. (이렇게 하지마세요ㅎㅎ)
class Main{
private Watcher watcher;
public Form(){
watcher = new Watcher(this);
watcher.start();
// do something main job..
}
public void doWhenCreatedFile(string path){
// do something..
}
}
// ======================================================
class Watcher{
private Main main;
public Watcher(Main main){
this.main = main;
// FileSystemWatcher 코드 생략..
}
private void FileSystemWatcher_Created(object sender, FileSystemEventArgs e)
{
main.doWhenCreatedFile(e.Name);
}
}
이러면 서로 종속성이 생기게 됩니다. 순환참조가 되는거죠.
Watcher 라는 class 는 분명 유틸성으로 재사용이 가능한 class 입니다.
하지만 다른곳에서 사용하려고 할때, Main 이라는 class 가 있기 때문에 Main도 가져가야됩니다.
아니면 Watcher2 를 만들거나? (말도안되는..)
Watcher 가 Main 을 호출해야하는데, Main class의 객체 없이 main 의 함수를 호출할까요?
그런걸 하는게 callback 함수죠. C# 에서는 delegate 나 Action 등을 사용합니다.
여기에선 더 간단히 사용하고 직관적인 Action 을 사용해보려고 합니다.
위의 코드를 Action 을 써서 다시 타이핑 해보겠습니다.
class Main{
private Watcher watcher;
public Form(){
watcher = new Watcher(doWhenCreatedFile); // 함수를 넘김
watcher.start();
// do something main job..
}
public void doWhenCreatedFile(string path){
// do something..
}
}
// ======================================================
class Watcher{
// private Main main; <-- 이거 대신 아래의 callback 이 같은 일을 해줌
private Action<string> callback;
// public Watcher(Main main){ <-- main 객체는 ㅂㅂ
// this.main = main; <-- 이것도 ㅂㅂ
public Watcher(Action<string> callback){ // Action 을 파라메터로 받음
this.callback = callback;
// FileSystemWatcher 코드 생략..
}
private void FileSystemWatcher_Created(object sender, FileSystemEventArgs e)
{
// main.doWhenCreatedFile(e.Name); <-- main 객체는 이제 안녕~
callback.Invoke(e.Name); // Invoke 외에 비동기로 BeginInvoke도 사용가능
}
}
이렇게 하면 Watcher 는 Main 외에 어느 Class 에서든 Watcher 만 불러와서 사용할 수 있습니다.
그림으로 간략히 설명하면
첫번째 코드는 이렇습니다.
다른 클래스들은 사용할 수 있는 방법이 없죠.
두번째 코드는 아래와 같습니다.
각자 클래스들이 Action 을 만들어서 넘기기만 하면 Watcher는 그 Action 을 실행해 줍니다.
사용하기 편해야 잘 쓰죠.
이게 최선의 방법은 아닙니다. 여러가지 방법이 있지만 그 중 하나입니다.
다만, 첫번째 코드와 같은 방법은 안 좋은 코드입니다.
그럼
즐코딩하세요~
'C# 기술' 카테고리의 다른 글
[Selenium] Page Load Timeout 설정하기 (0) | 2022.09.25 |
---|---|
[C#] ChromeDriver only supports characters in the bmp 해결하기 (0) | 2022.04.06 |
[C#] 크롤링에 유용한 라이브러리 HtmlAgilityPack (0) | 2021.10.31 |
[C#] 여러 개 Thread 사용 시 주의사항 (파라메터 사용 시) (0) | 2021.10.30 |
[C#] Tuple 사용하기 (0) | 2021.10.20 |
댓글