Схемы обработки сообщений
Важным требованием к включающим
сущностям, будь то класс, плод множественного
наследования, или контейнер, является
возможность проецирования свойств вложенных
объектов. То есть, эти сущности могут
обладать некоторыми свойствами тех классов,
которые в них включены. В контейнере данная
проблема решается за счёт использования
полиморфности свойств. Вполне достаточно
указать, что данный контейнер умеет обрабатывать
необходимый набор сообщений. Обработка
сообщений, в том числе спроецированных
от вложенных классов, может быть простой
или сложной, но в любом случае она реализуется
посредством схем.
Схема – это реакция контейнера
на определённое входное сообщение. В динамическом
контейнере схема обработки сообщений,
как правило, достаточно тривиальна. Входное
сообщение обычно либо проецируется на
все вложенные объекты, либо передаётся
активному в данный момент объекту. Иначе
обстоит дело со статическими контейнерами.
Здесь обработка сообщений является важным
инструментом реализации логики контейнера.
При разложении исходного сообщения на
множество сообщений к вложенным объектам
возможны две ситуации: некоторая последовательность
сообщений может быть обработана вложенными
объектами параллельно или последовательно.
То есть, при конструировании схем ясно
видны сообщения, которые допускают параллельную
обработку и те, которые её не допускают.
Параллельные участки могут в рамках одной
схемы сменяться последовательными участками
и наоборот. Точку, в которой необходимо
дождаться завершения обработки нескольких
сообщений, исполняемых параллельно во
вложенных классах, будем называть точкой
синхронизации. Сообщения, обрабатываемые
последовательно, разделяются точкой синхронизации
по умолчанию. Завершение схемы обработки
сообщения в контейнере тоже сопровождается
точкой синхронизации.
Основное значение схем контейнеров
состоит в том, что они позволяют отделить
логику работы вложенных объектов от логики
управления этими объектами или, что то
же самое, от логики взаимосвязи между
вложенными объектами. Такое разделение
логики приводит к двум эффектам: независимость
логических слоёв и значительное упрощение
иерархий элементарных классов. Независимость
логических слоёв основывается на том,
что при разработке конкретных классов
не надо решать вопросы взаимодействия
этого класса с другими классами, в том
числе и контейнерами, в которые он может
быть вложен. Любой класс должен соответствовать
своему назначению и поддерживать специфицированный
интерфейс. Как следствие данного положения,
можно отметить и тот факт, что в данном
случае всегда остаётся возможность разделения
текущего уровня на подуровни, без переделки
и перекомпиляции смежных уровней. В результате
можно вначале строить «грубую» модель,
а затем постепенно уточнять её, детализируя
подуровни. Это и есть правило локализации
для логических уровней. Реализация каждого
логического уровня является независимой
от других уровней или, говоря другими
словами, каждый логический уровень инкапсулирует
собственную реализацию. Например, линия
не должна «знать» о том, какие графические
примитивы будут созданы на её основе;
атому нет дела до того, в образовании
каких молекул он примет участие; структурным
группам Ассура нет дело до того, какие
механизмы будут создаваться на их основе.
При обработке сообщения,
возможно, возникнет такая цепочка сообщений
к вложенным объектам, когда результат
обработки сообщения одним объектом должен
быть передан для последующей обработки
на другой вложенный объект. Возникает
соблазн связать выход одного объекта с
входом другого, минуя контейнер. Однако
так делать не следует. Обмен сообщениями
должен происходить только через контейнер.
Это обусловлено тем, что состояние контейнера
или контекста могло измениться за то время,
пока первый объект обрабатывал сообщение.
Изменение состояния контейнера может повлиять
на порядок обработки исходного сообщения.
Более подробно о состояниях контейнера
и контексте будет сказано ниже.
Схема может обладать локальными
данными. Эти данные обеспечивают сохранение
промежуточных результатов, полученных
в результате обращений к свойствам вложенных
объектов. Локальные данные схем существуют
только при работе схемы и не сохраняются
между вызовами схемы. Можно провести аналогию
между локальными данными схемы и локальными
данными подпрограммы. Суть их аналогична.
Точно также как и подпрограмма, схема
может иметь локальные данные, сохраняемые
между её вызовами. Эти данные расширяют
структуру данных контейнера. Наконец,
схема может взаимодействовать с глобальными
данными контейнера, которые доступны и
другим схемам.
При проектировании контейнера
нам известны те сообщения, которые он
должен уметь обрабатывать. Очевидно, что
и логика обработки сообщений тоже известны.
Но тогда нужно допустить, что последовательность
сообщений к вложенным объектам, нам также
известна. Следовательно, схема на физическом
уровне представляет собой ничто иное,
как последовательность сообщений к вложенным
объектам и свойствам самого контейнера
разделённая точками синхронизации. Отсюда
можно заключить, что приход сообщения
к контейнеру производит запуск (проигрывание)
соответствующей последовательности сообщений
к вложенным объектам в заданном порядке.
Но поскольку схемы являются единым механизмом
реализации свойств контейнеров, то и проигрывание
последовательности сообщений к вложенным
объектам происходит единообразно, и не
зависит ни от типа сообщений, ни от класса
контейнера. Что, в свою очередь, позволяет
говорить не о программировании, а об общих
принципах конструирования схем.
При конструировании схем
весьма удобно пользоваться графическими
средствами, которые наглядно отображают
последовательность обработки входного
сообщения посредством обращения к свойствам
вложенных объектов. Конечной целью проектирования
схемы является получение последовательности
сообщений к вложенным объектам и свойствам
самого контейнера.
В целом ряде задач схемы
могут создаваться динамически, например,
на основе запроса пользователя. В качестве
такого примера можно рассмотреть запросы
пользователя к базе данных. Запрос может
быть оформлен на языке SQL,
а затем переведён в набор схем, которые
поступают на обработку.
|