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.
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àmHandler, nhận một thông báo kiểuconst char*. Tạo một structEventchứ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 0subscribe: 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ượngfire: 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áoalert: in ra[ALERT], theo sau là thông báocounter: 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
Chương trình của bạn sẽ nhận:
- Số trình xử lý cần đăng ký (1, 2 hoặc 3)
- 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;
}
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
1Kiến thức cơ bản về lập trình mô-đun
Tệp tiêu đềInclude guardTệp mã nguồnHàm staticÔn tập: Máy tính mô-đun4Tính đóng gói
Khái niệm con trỏ mờĐịnh nghĩa struct mờHàm truy xuất và hàm gánKiểm tra tính hợp lệ trong hàm gánÔn tập: Hộp bí mật2Đối tượng và phương thức
Struct dưới dạng đối tượngCon trỏ 'Self'Tính đúng đắn của constCon trỏ và giá trịPhương thức hỗ trợÔn tập: trình quản lý Point5Dự án: Tài khoản ngân hàng đơn giản
Thiết lập dự ánTriển khai tài khoản3Vòng đời đối tượng
Mẫu hàm khởi tạoMẫu hàm hủyKhởi tạo trên ngăn xếpSao chép sâuÔn tập: lớp bao bọc chuỗi6Kế thừa bằng cách kết hợp
Nhúng structQuy tắc thành viên đầu tiênTruy cập thành viên lớp chaUpcastingÔn tập: hệ phân cấp hình dạngTự luyện tập: Trình biên dịch C online