[프로그래밍] Callback 함수의 개념에 대한 개인적인 생각

2020. 4. 25. 23:41프로그래밍(Programming)/C++

 내 개인적인 생각이지만 주변에서 컴퓨터 공학 / 컴퓨터 과학을 전공한 사람들 중에서도, 심지어 현업에서 프로그래밍을 하더라도 callback이라는 개념에 대해서 알기까지는 시간이 걸릴 수 있다. 단순히 개념이 어렵다기보다는 사용하면서도 callback이란 걸 모르거나 platform, framework을 경험하기 이전에는 실제로 사용해보는 일이 많지 않을 수 있기 때문이다.

 하지만, 프로그램이 커지고 여러 사람이 협업하게 되면 필수적으로/필요에 의해 슬슬 등장하게 되는 것이 callback이라고 생각한다.

 

Callback 함수에 대해 알아보기 전에, 일반적인 함수의 호출에 대해서 생각해 본다.

#include <iostream>


void foo() {
    std::cout << "Normal Function Call" << std::endl;
}


int main() {
    foo();
    return 0;
}

 

위 코드를 실행하면 main함수가 실행되며 그 이후에 바로 foo() 함수를 호출하게 된다.

 

이때 이 코드를 작성한 사람은, 정확하게 foo함수가 몇 번(1회) 호출 될 것이며 언제 호출(main 함수 실행 직후)될지 정확하게 알 수 있다.

 

 

그럼 이제 일반 함수의 호출에 대해 알았으니, 콜백 함수(callback function)에 대해 알아보자.

먼저 callback이라는 개념을 떠올리기 이전에 다음과 같은 사람들이 있다고 생각을 한번 해봅시다.

 

 - A: Android UI Component 개발자 (e.g., Button)

 - B: Android Application 개발자 (e.g., Button을 배치하여 만든 계산기 앱)

 - C: Android Application 사용자 (e.g., B가 만든 계산기 앱을 다운로드하여 사용하는 사람)

 

A라는 framework 개발자는 어플리케이션에서 배치할 각종 UI component(e.g., Button, EditText, TextView, and etc.)들을  만든다.

B라는 개발자는 A가 만든 Button을 이용해서 계산기에 필요한 각종 숫자, 연산자 등을 버튼으로 구현하여 배치했다고 해봅시다.

 

여기서 A라는 개발자와 B라는 개발자는 모두 각각의 버튼이 언제 어떻게 사용될지 알 수 없습니다. 그건 계산기 어플의 사용자인 C만이 알 수 있습니다.

그럼 여기서 A라는 개발자가 할 수 있는 일과, B라는 개발자가 할 수 있는 일이 무엇인지에 대해서 따라가다 보면 자연스럽게 Callback 함수의 정체에 대해서 알 수 있습니다.

 

A (UI component 개발자) -  Callback 함수 호출 코드 개발자

간단하게 개념적인 코드를 작성해 보았습니다. A 라는 개발자는 아래와 같이 Button 클래스를 만듭니다.

Button 클래스에는 Function 멤버(호출가능)를 가지고 있고, 버튼이 눌렸을 때 onButtonClicked가 호출되며 mFcn 함수를 호출합니다.

class Button {
  Function mFcn;
  String mTitle;

  void setTitle(String title) {
    mTitle = title;
  }

  void setOnClickListener(Function fcn) {
    mFcn = fcn;
  }

  void onButtonClicked() {
    mFcn(...);
  }

}

 

B (Application 개발자) - Callback 함수 작성자

A가 만든 Button 클래스를 이용하여 계산기를 구현합니다.

TextView mResultView;

Button mNum0;
Button mNum1;
Button mNum2;
...

mResultView.setText("0");
...
mNum0.setText("0");
mNum1.setText("1");
mNum2.setText("2");
...

 

각각의 버튼이 눌렸을 때의 동작을 구현한다.



// 숫자 0이 눌렸을 때에 대한 처리
mNum0.setOnClickListener(new Function()...);

// 숫자 1이 눌렀을 때에 대한 처리
mNum1.setOnClickListener(new Function() {
  // TextView에 숫자 0을 추가한다.
  mResultView.appendText(1);
});

// 숫자 2가 눌렀을 때에 대한 처리
mNum2.setOnClickListener(new Function()...);
...

 

C (Application 사용자) - Callback 함수 주체

C가 버튼을 누를 때 마다, A가 만든 코드(Button의 setOnButtonClicked())에 의해 B가 만든 함수(new Function...)가 호출됩니다.

여기서 B가 만든 함수를 callback 함수라고 부릅니다.

즉, A와 B는 로직만 작성하고 C의 의지에 따라 callback 함수가 불리게 됩니다.

 

 

결론

어떤 분야에서 프로그래밍을 하느냐에 따라 다르겠지만, 오늘 설명드린 내용에 따른 Callback 함수의 특징은 "개발한 사람이 명시적으로 호출하는 것이 아니라, 다른 주체에 의해 호출되는 함수"입니다.

 

즉, Callback 함수의 개발자는 함수가 불렸을 때의 동작만 정의하고, 실제로 그 함수가 불릴 것인지, 언제 불릴지는 알 수 없는 것입니다.