Menu
CoddyTech

Hệ thống sự kiện

Thuộc phần Lập trình hướng đối tượng trong hành trình C của Coddy. Bài học 61 trên 61.

challenge icon

Thử thách

Dễ

Hãy xây dựng một Hệ thống thông báo: một kiến trúc hướng sự kiện, trong đó nhiều trình xử lý có thể đăng ký nhận một sự kiện và phản hồi khi sự kiện được kích hoạt. Mẫu này là nền tảng của lập trình phản ứng và các framework GUI.

Bạn sẽ sắp xếp code trong ba tệp:

  • event.h: Định nghĩa kiểu con trỏ hàm Handler, nhận một thông báo kiểu const char*. Tạo một struct Event chứa mảng có tối đa 5 trình xử lý và số lượng trình xử lý đã đăng ký. Khai báo các hàm để khởi tạo sự kiện, đăng ký trình xử lý và kích hoạt sự kiện để thông báo cho tất cả bên đăng ký.
  • event.c: Triển khai hệ thống sự kiện:
    • init_event: nhận một con trỏ Event và đặt số lượng trình xử lý thành 0
    • subscribe: nhận một con trỏ Event và một Handler, thêm trình xử lý vào mảng nếu còn chỗ (số lượng nhỏ hơn 5), rồi tăng số lượng
    • fire: nhận một con trỏ Event và một chuỗi thông báo, sau đó gọi từng trình xử lý đã đăng ký với thông báo đó theo thứ tự đăng ký
  • main.c: Tạo ba hàm trình xử lý khác nhau, mỗi hàm phản hồi sự kiện theo cách riêng:
    • logger: in ra [LOG] , theo sau là thông báo
    • alert: in ra [ALERT] , theo sau là thông báo
    • counter: dùng một biến static để đếm số lần hàm được gọi, rồi in ra [COUNT] X, trong đó X là số đếm hiện tại
    Đọc một số nguyên cho biết số trình xử lý cần đăng ký (1, 2 hoặc 3). Đăng ký số trình xử lý đó theo thứ tự: trước tiên là logger, tiếp theo là alert (nếu từ 2 trở lên), rồi đến counter (nếu là 3). Đọc một chuỗi thông báo, sau đó kích hoạt sự kiện với thông báo đó.

Chương trình của bạn sẽ nhận:

  1. Số trình xử lý cần đăng ký (1, 2 hoặc 3)
  2. Thông báo cần phát đi

Đầu ra ví dụ khi đầu vào là 3 và System started:

[LOG] System started
[ALERT] System started
[COUNT] 1

Đầu ra ví dụ khi đầu vào là 2 và Warning detected:

[LOG] Warning detected
[ALERT] Warning detected

Đầu ra ví dụ khi đầu vào là 1 và Hello:

[LOG] Hello

Điều này minh họa tính đa hình thông qua con trỏ hàm: cùng một lời gọi fire sẽ kích hoạt những hành vi hoàn toàn khác nhau, tùy vào các trình xử lý đã đăng ký. Mỗi trình xử lý phản hồi sự kiện theo cách riêng, cho thấy thiết kế hướng sự kiện có tính tách biệt.

Tự làm thử

#include <stdio.h>
#include <string.h>
#include "event.h"

// TODO: Triển khai bộ xử lý logger
// In ra "[LOG] " rồi đến thông điệp
void logger(const char* message) {
    // TODO: Triển khai
}

// TODO: Triển khai bộ xử lý alert
// In ra "[ALERT] " rồi đến thông điệp
void alert(const char* message) {
    // TODO: Triển khai
}

// TODO: Triển khai bộ xử lý counter
// Dùng biến tĩnh để đếm số lần gọi
// In ra "[COUNT] X", trong đó X là số lần gọi hiện tại
void counter(const char* message) {
    // TODO: Triển khai bằng biến tĩnh
}

int main() {
    // Đọc số lượng bộ xử lý cần đăng ký
    int num_handlers;
    scanf("%d", &num_handlers);
    getchar(); // Đọc ký tự xuống dòng
    
    // Đọc thông điệp
    char message[256];
    fgets(message, sizeof(message), stdin);
    message[strcspn(message, "\n")] = '\0'; // Xóa ký tự xuống dòng
    
    // TODO: Tạo và khởi tạo Event
    
    // TODO: Đăng ký các hàm xử lý dựa trên num_handlers
    // 1 hàm xử lý: logger
    // 2 hàm xử lý: logger, alert
    // 3 hàm xử lý: logger, alert, counter
    
    // TODO: Kích hoạt sự kiện với thông điệp
    
    return 0;
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch C online