이벤트 시스템
Coddy C 여정의 Object Oriented Programming 섹션에 포함된 레슨 — 61개 중 61번째.
챌린지
쉬움여러 핸들러가 이벤트에 구독하고 이벤트가 발생할 때 응답할 수 있는 이벤트 기반 아키텍처인 알림 시스템(Notification System)을 구축해 보겠습니다. 이 패턴은 반응형 프로그래밍과 GUI 프레임워크의 핵심입니다.
코드는 다음 세 개의 파일로 구성됩니다:
event.h:const char*메시지를 매개변수로 받는Handler함수 포인터 타입을 정의합니다. 최대 5개의 핸들러 배열과 등록된 핸들러의 개수를 저장하는Event구조체를 생성합니다. 이벤트 초기화, 핸들러 구독, 모든 구독자에게 알림을 보내는 이벤트 발생(fire)을 위한 함수들을 선언합니다.event.c: 이벤트 시스템을 구현합니다:init_event— Event 포인터를 받아 핸들러 개수를 0으로 설정합니다.subscribe— Event 포인터와 Handler를 받아, 공간이 있는 경우(개수가 5 미만) 배열에 핸들러를 추가하고 개수를 증가시킵니다.fire— Event 포인터와 메시지 문자열을 받아, 등록된 각 핸들러를 구독된 순서대로 해당 메시지와 함께 호출합니다.
main.c: 이벤트에 고유한 방식으로 응답하는 세 가지 핸들러 함수를 생성합니다:logger—[LOG]뒤에 메시지를 출력합니다.alert—[ALERT]뒤에 메시지를 출력합니다.counter— 정적(static) 변수를 사용하여 호출된 횟수를 세고,[COUNT] X를 출력합니다 (X는 현재 횟수).
프로그램은 다음을 입력받습니다:
- 구독할 핸들러의 개수 (1, 2 또는 3)
- 방송할 메시지
입력이 3과 System started일 때의 출력 예시:
[LOG] System started
[ALERT] System started
[COUNT] 1입력이 2와 Warning detected일 때의 출력 예시:
[LOG] Warning detected
[ALERT] Warning detected입력이 1과 Hello일 때의 출력 예시:
[LOG] Hello이것은 함수 포인터를 통한 다형성을 보여줍니다. 동일한 fire 호출이 어떤 핸들러가 구독되었는지에 따라 완전히 다른 동작을 유발합니다. 각 핸들러는 동일한 이벤트에 대해 자신만의 방식으로 응답하며, 이는 이벤트 기반 설계의 결합도 낮은(decoupled) 특성을 잘 보여줍니다.
직접 해보기
#include <stdio.h>
#include <string.h>
#include "event.h"
// TODO: logger 핸들러 구현
// "[LOG] " 뒤에 메시지를 출력합니다
void logger(const char* message) {
// TODO: 구현
}
// TODO: alert 핸들러 구현
// "[ALERT] " 뒤에 메시지를 출력합니다
void alert(const char* message) {
// TODO: 구현
}
// TODO: counter 핸들러 구현
// static 변수를 사용하여 호출 횟수를 계산합니다
// "[COUNT] X"를 출력하며, 여기서 X는 현재 카운트입니다
void counter(const char* message) {
// TODO: static 변수를 사용하여 구현
}
int main() {
// 구독할 핸들러의 개수를 읽습니다
int num_handlers;
scanf("%d", &num_handlers);
getchar(); // 개행 문자 소비
// 메시지를 읽습니다
char message[256];
fgets(message, sizeof(message), stdin);
message[strcspn(message, "\n")] = '\0'; // 개행 문자 제거
// TODO: Event 생성 및 초기화
// TODO: num_handlers에 따라 핸들러 구독
// 핸들러 1개: logger
// 핸들러 2개: logger, alert
// 핸들러 3개: logger, alert, counter
// TODO: 메시지와 함께 이벤트 발생(fire)
return 0;
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.