Многоуровневая Модель Обработки Событий

Событие в объектно-ориентированном программировании (ООП) — это сообщение, которое возникает в различных точках исполняемого кода при выполнении определенных условий.

Эти сообщения передаются обработчикам (слушателям), что позволяет своевременно реагировать на изменившееся состояние системы.

Программирование, управляемое событиями, очень популярно.

Эта парадигма программирования гласит, что выполнение программы определяется событиями — действиями пользователя (клавиатуры, мыши), сообщениями от других программ и потоков, событиями операционной системы и т. д. Преимущества и сфера применения событийной модели чрезвычайно широки:

  • при соединении объектов с событиями объектам не нужно «знать» друг о друге;
  • этот механизм явно вписывается в концепцию ООП;
  • этот механизм позволяет легко реализовать пользовательские интерфейсы, где каждое действие пользователя является событием; достаточно «подцепить» обработчики этих событий;
  • при реализации серверных приложений событийная модель позволяет избавиться от создания множества сервисных процессов;
  • Модель событий также часто используется при программировании игр, в которых управляется множество объектов.

Существуют шаблоны проектирования, так или иначе связанные с обработкой событий: Observer, Command, Chain of Responsibility и многие другие.

Эти шаблоны используются во многих моделях обработки событий.

Однако различные реализации событийной модели накладывают ряд ограничений на возможности разработки программ:

  • При обработке события нельзя выбрать основной обработчик; все обработчики равны друг другу;
  • при обработке события обработчики ничего не знают друг о друге и текущей ситуации, что не позволяет программисту в полной мере реализовать задуманный функционал;
  • вам придется добавить дополнительную функциональность, если вы хотите выбрать результирующий обработчик.

Список перечисленных ограничений неполный, но эти ограничения являются наиболее существенными.

В данной статье предлагается реализация более сложной событийной модели, которая снимет все вышеперечисленные ограничения.

При разработке программного обеспечения с использованием данной модели обработки событий последовательность этапов обработки следующая:

  1. Для обработки своих событий подключаются необходимые слушатели.

  2. В программном коде запускается событие.

  3. Выполняется «первый раунд» обработки, всем слушателям, подключенным к обработке этого события, дается время на первичную обработку, в течение которого каждый слушатель может получить свои собственные данные, данные от инициатора события, а также задать любые данные для передачи в «второй тур» и подать заявку на оформление мероприятия во «втором туре».

  4. Среди всех слушателей этого события выбирается слушатель, подавший запрос с наивысшим приоритетом обработки, и ему предоставляется право на обработку события во «втором раунде».

    В ходе этой обработки он может получать данные от инициатора, свои собственные данные и данные от своего процессора «первого круга».

    После завершения обработки данные могут быть возвращены непосредственно инициатору события.

Рассмотрим преимущества данной модели:
  • Можно один и тот же обработчик «подцепить» к разным событиям или даже к одному и тому же событию, но с разными собственными данными.

  • Возможна обработка широкого спектра событий.

    Например, добавление нового пользователя, отображение дизайна страницы сайта и т.п.

    В этом случае событие добавления нового пользователя может обрабатываться только «первым кругом», а событие отображения дизайна страницы сайта должно обрабатываться.

    в «два круга».

  • Выполняется только один обработчик «второго раунда» (Рассмотрим выходное событие дизайна сайта: на первом раунде обработчики, анализируя состояние системы, выдвигают приоритеты обработки события, и только на «втором раунде» выполняется один из них формируют дизайн страницы сайта).



Многоуровневая модель обработки событий

На картинке представлена схема реализации данной модели.

Эта реализация изначально опирается на цепочку вызовов.

Ниже приведен пример реализации модели на PHP.

  • События – основной класс.

    Только его объект может создать сам пользователь.

    Этот класс предоставляет возможность запускать события и присоединять обработчики событий.

    • новыйСлушатель — позволяет добавить новый слушатель и сразу его «настроить» (добавление происходит через адаптер для Events_Listener — Events_Listener_adapterSET).

    • новое событие — позволяет настроить новое событие, а затем инициировать его (это действие происходит через адаптер для Events_Fire — Events_Fire_adapterSET).

    Остальные классы прозрачно для пользователя подключаются к рабочему процессу:
    • События_Fire — предоставляет общий интерфейс для работы с событиями, который ограничен адаптерами;
    • События_Fire1 – при вызове первого круга обработки.

      Этот класс позволяет получить все доступные данные о текущем состоянии, добавить второй обработчик круга, а также установить его приоритет (через адаптер Events_Fire2_adapterSET);

    • События_Fire2 — при вызове результирующего обработчика («второй круг»).

      Этот класс позволяет получить все доступные данные, включая данные из обработчика «первого круга»;

    • События_Слушатель — предоставляет общий интерфейс для работы с обработчиком событий.

      Методы этого класса также используют адаптеры Events_Fire1, Events_Fire2;

    • События_Данные – класс для хранения и передачи данных внутри модели событий.

Давайте посмотрим на примере, как работает эта модель:
   

class SampleListener { public function Fire1(Event_fire1 $EF1) { $EF1->setFinal(Array($this,”Fire2”), $EF1->getListenerData()->sort); } public function Fire2(Event_fire2 $EF2) { return ($EF2->getListenerData()->sort() + $EF2->getFireData()->sort()); } } $listener = new SampleListener(); $data1 = new Events_Data(); $data1->sort = 10; Events::newListener("sampleModul", "sampleEvent", Array($listener, 'Fire1'))->setData($data1); $data2 = new Events_Data(); $data2->sort = 20; Events::newListener("sampleModul", "sampleEvent", Array($listener, 'Fire1'))->setData($data2); $data3 = new Events_Data(); $data3->sort = 30; Echo Events::newEvent("sampleModul", "sampleEvent")->setData($data3)->fire();

После запуска события образецСобытие метод будет вызываться Огонь1 слушатель $listener с первыми данными (sort=10, это приоритет, который он установит для окончательной обработки) , а затем тот же метод будет вызван с другими данными (sort=20, 20> 10, поэтому слушатель с этими данными получит право на финальную обработку события) .

Наконец метод будет вызван Огонь2 (Обработчик тот же, но данные — $data2) .

Данные о событии (сортировка=30) добавлено с данными от прослушивателя (сортировка=20) .

В результате событие вернет нам число 50, которое отобразится на экране.

Этот пример показывает, что один и тот же обработчик может по-разному реагировать на событие в зависимости от данных прослушивателя.

Он также демонстрирует процесс обработки события, включая результирующий одиночный вызов.

Огонь2 (Представьте, что в этом методе, например, генерируется дизайн страницы сайта, а данные являются внешним контекстом для обработки события) .

Внедрив эту модель обработки событий, мы смогли снять все вышеперечисленные ограничения.

На данный момент модель ориентирована на конкретный продукт (есть паразитные методы, необходимые только в этом продукте), но при наличии интереса код можно подготовить для публичной версии.

Вы также можете реализовать эту модель на других языках программирования.

В cpp вы можете передавать указатель как данные и использовать reinterpret_cast или использовать шаблоны в методах обработки.

Реализация в каждой конкретной ситуации может незначительно отличаться, но суть заключается в реализации двух и более уровней.

Теги: #php #events #Алгоритмы #Алгоритмы

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.