logo
Проектирование инт-прил / лекции / Проектирование инет приложений

Событийно-ориентированное программирование

В традиционном приложении поток выполнения обычно прост и линеен. Приложение загружается в память, начинает выполняться в точке А, завершает работу в точке Б и выгружается из памяти. Если мы говорим о сервере, то мы создаем на каждого из подключившихся клиентов свой процесс или поток, при этом в рамках процесса (потока) приложение по-прежнему выполняется линейно, от начала и до конца. Применительно к архитектуре клиент-сервер, все то же самое выглядит следующим образом: сервер получает от клиента запрос и занимается данным клиентом до тех пор, пока полностью не обработает этот запрос и не выдаст клиенту результат. Такой подход имеет ограничение по количеству одновременно подключенных клиентов, так называемая "проблема 10 000" - начиная с некоторого достаточно большого числа одновременных пользователей, серверная часть уже не справляется с нагрузкой. Возникает это явление по двум причинам:

Событийно-ориентированное программирование - это такой подход, при котором в коде в явном виде выделяется главный цикл приложения. Главный цикл работает с событиями, получая их из операционной системы и обрабатывая. Длительное выполнение обработчика события при этом недопустимо, поскольку при этом программа не сможет реагировать на другие события. Под "событием" подразумеваются как инициированные пользователем (движение мышкой, нажатие на клавиатуре), так и инициируемые самой операционной системой либо другими приложениями - появление в буфере готовых для чтения данных с диска, поступление по сети сообщения от другого приложения и так далее. Серверное приложение при событийно-ориентированном программировании реализуется на системном вызове, получающем события одновременно от многих источников. При обработке событий используются исключительно неблокирующие операции ввода-вывода, чтобы ни один дескриптор при его опросе не препятствовал обработке событий от других дескрипторов.

Написание событийно-ориентированных программ тесно связано с другой парадигмой - с конечными автоматами. Определяющими для автоматного программирования являются следующие особенности:

Такой подход позволяет делать шаг одного и того же автомата для разных подключившихся клиентов, поскольку состояние автомата между шагами однозначно определено и не зависит от предыдущего состояния автомата.

Рассмотренное выше объектно-ориентированное программирование прекрасно сочетается с событийно-ориентированным. Понятие объекта представляет собой удачный инструмент реализации модели конечного автомата. При применении парадигмы автоматного программирования в объектно-ориентированных языках обычно модели автоматов представляются в виде классов, состояние автомата описывается внутренними (закрытыми) полями класса, а код шага автомата оформляется в виде метода класса, причём такой метод скорее всего оказывается единственным открытым методом (не считая конструкторов и деструкторов), изменяющим состояние автомата. Другие открытые методы могут служить для получения информации о состоянии автомата, но не меняют его. Все вспомогательные методы (например, методы-обработчики отдельных состояний или их категорий) в таких случаях обычно убирают в закрытую часть класса.

На данный момент существует несколько программных средств, предоставляющих возможности для разработки серверного событийно-ориентированного кода. Главный цикл программы уже кем-то был написан и отлажен, среда предоставляет разработчику ряд предопределенных методов, перекрытием которых можно получить возникшее событие. Программирование при этом сводится к реализации конкретных обработчиков событий. При этом заранее не определена ни последовательность возникновения этих событий, ни источник событий (конкретный клиент или другое приложение). Событийно-ориентированное программирование позволяет строить системы с высочайшим (на данный момент) масштабированием.