Система событий
Часть раздела Объектно-ориентированное программирование путешествия по C на Coddy. Урок 61 из 61.
Задание
ЛегкоДавайте создадим систему уведомлений: архитектуру, управляемую событиями, в которой несколько обработчиков могут подписаться на событие и реагировать, когда оно срабатывает. Этот шаблон лежит в основе реактивного программирования и GUI-фреймворков.
Вы организуете код в трёх файлах:
event.h: Define тип указателя на функциюHandler, которая принимает сообщениеconst char*. Создайте структуруEvent, содержащую массив максимум из 5 обработчиков и количество зарегистрированных обработчиков. Объявите функции для инициализации события, подписки обработчика и срабатывания события для уведомления всех подписчиков.event.c: Реализуйте систему событий:init_event: принимает указатель Event и устанавливает количество обработчиков равным 0subscribe: принимает указатель Event и Handler, добавляет обработчик в массив, если есть место (count меньше 5), и увеличивает countfire: принимает указатель Event и строку сообщения, затем вызывает каждый зарегистрированный обработчик с этим сообщением в порядке их подписки
main.c: Создайте три разные функции-обработчика, которые уникальным образом реагируют на события:logger: выводит[LOG], за которым следует сообщениеalert: выводит[ALERT], за которым следует сообщениеcounter: использует статическую переменную для подсчёта количества вызовов, затем выводит[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 запускает совершенно разное поведение в зависимости от того, на какие обработчики выполнена подписка. Каждый обработчик по-своему реагирует на одно и то же событие, демонстрируя слабосвязанную природу архитектуры, управляемой событиями.
Попробуйте сами
#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
// Использует статическую переменную для подсчёта вызовов
// Выводит "[COUNT] X", где X — текущее значение счётчика
void counter(const char* message) {
// TODO: Реализовать со статической переменной
}
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: Вызвать событие с сообщением
return 0;
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы модульного программирования
Заголовочные файлыСтражи включенияИсходные файлыСтатические функцииПовторение: Модульный калькулятор4Инкапсуляция
Концепция непрозрачных указателейОпределение непрозрачных структурГеттеры и сеттерыВалидация в сеттерахИтоги: Секретный ящик2Объекты и методы
Структуры как объектыУказатель 'Self'Константная корректностьУказатель против значенияВспомогательные методыИтоги: Point Manager5Проект: Простой банковский счет
Настройка проектаРеализация счета3Жизненный цикл объекта
Паттерн «Конструктор»Паттерн «Деструктор»Инициализация в стекеГлубокое копированиеПовторение: String Wrapper6Наследование через композицию
Встраивание структурПравило первого элементаДоступ к элементам родителяUpcastingПовторение: Иерархия фигур9Проект: Рисование фигур
Обзор проектаРеализация кругаРеализация прямоугольникаПолиморфное использованиеКонтейнер фигурПотренируйтесь самостоятельно: Онлайн-компилятор C