Стили и методы программирования

         

Событие, сообщение, демон


Упомянутое ранее (утверждение (5.2)) качество

Подготовка информации для действий в ходе распознавания условий применимости действий, (13.1)

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

Следует заметить, что есть еще одна особенность, общая для двух стилей: сентенциального и событийного.

Отделение проверки условий от выполнения действий (13.2)

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

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

Из потребности такой обработки, собственно говоря, и сформировался событийно-ориентированный стиль программирования.
Наиболее очевидная область его адекватного применения - реализация интерактивных взаимодействий программы с пользователем и решение других подобных задач (например, тех, которые требуют опроса датчиков состояния каких-либо технологических процессов).
В частности, при взаимодействии с пользователем чаще всего достаточно таких событий, как нажатие на клавишу, перемещение курсора мыши, указание световой кнопки и т. п. Не случайно именно те прерывания, которые способна перенаправить операционная система для обработки на уровень пользовательской программы, стали основой для выработки систем событий, реакция на которые задается в событийно-ориентированном стиле. События этого рода можно передать от одного обработчика к другому, не нарушая условий адекватного применения данного стиля: для этого достаточно объявить такое перенаправление события порождением нового события.
Но требуется также генерация событий, не связанных с прерываниями. К примеру, программируя в событийно-ориентированном стиле, естественно объявить событием ситуацию, когда значение одной переменной становится больше другой. Однако такого рода свойства вычислительного процесса никак не отражаются в системе прерываний, а потому обычные языковые средства событийно-ориентированного программирования (например, в Delphi), часто провозглашаемые как универсальные, здесь не помогут. Необходимы иные механизмы, которые уводят программиста из области шаблонов проектов, стандартизующих обработку событий.
Об этом обстоятельстве, ограничивающем применимость подхода, предпочитают умалчивать, и, как обычно бывает в подобных ситуациях, при беглом знакомстве с соответствующими средствами могут возникнуть ни на чем не основанные ожидания с последующими разочарованиями и даже отторжением стиля, хорошо работающего на своем месте.
Примером языка, до некоторой степени ориентированного на событийно-ориентированное программирование, может служить Perl.
Событийный стиль удобен не только на уровне конкретного программирования. Часто концептуальное осмысление задачи полезно проводить в терминах системы событий, а уж затем решать, как реализовывать систему: непосредственно использовать события как средство управления, моделировать событийное взаимодействие имеющимися средствами или вообще отказаться от этого механизма в данной разработке.


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

  • Необходимость рассмотрения в качестве событий двух фактов: начала и завершения распознавания конструкции, поскольку именно с ними, а не с конструкцией в целом связываются семантические действия.
  • Для обсуждаемой задачи существенно, что события возникают не в произвольном порядке, их множество имеет вполне определенную структуру. Не удивительно, что эта структура в точности соответствует синтаксической структуре текста: например, событие завершения распознавания конструкции не может возникать раньше, чем возникнет событие начала конструкции.
  • Следствием этой структуры является понятие ожидания вполне определенных, а не произвольных событий. Если ожидание не оправдалось, то это можно считать событием еще одного вида: ошибочная ситуация. Количество таких событий в точности равно числу наборов ожидаемых событий.

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


Нет никакого противоречия между двумя схемами, и единственное различие между ними в том, что при синтаксическом управлении ожидание события оказалось возможным подменить прямым вызовом подпрограммы. Иными словами, в схеме трансляции удается статически, до выполнения программы вычислить события, наступление которых требует вызова их обработчиков (семантических подпрограмм). Вообще, сопрограммное взаимодействие можно трактовать как статически вычисленную событийность1).
Разумеется, рамки событийного программирования много шире тех случаев, когда можно статически определять необходимость активизации обработчика. Полезно объединение генерации событий с их обработкой, и за счет него можно растворять события в программе. В частности, и по этой причине следует рассматривать событийное программирование как самостоятельный стиль. Но интересны и такие случаи, когда объединение, хотя и возможно, но не делается. Конкретный пример - XML/XSL технология, для которой разделение структуры и интерпретации текста считается принципиальным: это позволяет строить съемные системы обработки, иметь несколько независимых таких систем для разного назначения. В своей сфере применения многовариантность имеет большие преимущества, но, как всегда, перенос принципов данной технологии куда угодно чреват уже не раз отмеченной неадекватностью.

Содержание раздела