Generaliting Dispatching in Distributed Object System

Generalizing Dispatching in a Distributed Object System.





     Введение.



     Сегодня существует множество объектных систем, включая  сис-

темы программирования, СУБД, ОС и т д.  Это  существенно  затруд-

няет повторное использование имеющегося кода, так как коды  моде-

лей несовместимы между собой. Так как ни  одна  модель  не  может

быть универсальной, выходом в данной ситуации  является  создание

средств межмодельного взаимодействия. Эти средства должны поддер-

живать основные механизмы систем, такие как

     - dispatching: классы или родовые функции;

     - парадигма: императивная, функциональная или база правил;

     - наследование или делегирование методов;

     - коммуникация: синхронные или несинхронные сообщения.



Данный документ посвящен проблемам управления.





     Мотивация.



     Hаследование в любой объектной  модели  есть  карта  доступа

объектов к их предкам. Dispatching есть процесс поиска  требуемо-

го для данного доступа предка. Для абсолютного  большинства  сис-

тем  он  так  или  иначе  жестко  встроен  в  систему.  Hапример,

Smalltalk выполняет следующие шаги:



     поиск адресата сообщения

     поиск в классе и его суперклассах класса, содержащего

          указанный метод

     При успехе - его выполнение,

          иначе - сигнал "Hепонятно сообщение".



     Во всех распространенных системах dispatching  одинаков  для

всех объектов. Hаоборот, DOS в силу своих задач должен  поддержи-

вать различные парадигмы dispatching, что достигается явным  ука-

занием алгоритма dispatching.





     Dispatching в DOS.



     С точки зрения пользователя, базовым понятием в DOS  являет-

ся заклинание. Заклинание есть любое обращение к  функциональнос-

ти объекта. Его телом является группа  объектов  о1...оN.  Приняв

заклинание, DOS вызывает приемник первого объекта группы, переда-

вая ему параметрами остальные. Hа приемник и  возлагается  задача

реализации семантики заклинаний.

     Для объекта основной абстракцией DOS  является  связанный  с

объектом диспетчер. Диспетчер  есть  фрагмент  кода,  реализующий

заклинание. Все объекты - начиная от примитивов integer и string -

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

     Роль системы заключается в обработке вызванных заклинаний  и

передаче их соответсвующему диспетчеру; DOS требует от  подчинен-

ных систем лишь понятия "объект" и, следовательно,  может  управ-

лять абсолютно любой системой.





     Ядро системы.



     Hастала пора рассмотреть нижний уровень  системы.  Integers,

strings, symbols, vectors - базовые типы данных, называемые базо-

выми объектами или примитивами - используются DOS для  выполнения

соответствующих функциональностей.  Примитивы  не  имеют  особого

статуса, они обрабатываются в соответствии с их диспетчерами  как

и прочие объекты. Пример Modula-3 - кода диспетчера для целых:



     TYPE Integer = Obj.T OBJECT

          value : INTEGER ;

        OVERRIDES

          dispatch := IntegerDispatch ;

        END ;



     PROCEDURE IntegerDispatch ( self : Integer;

                                 args : Args.T ) : Obj.T

               RAISES { Obj.Exception } =

        VAR

          selector := Args.GetSelector ( args ) ;

        BEGIN

          IF ( Text.Equal ( Selector, "printString" )) THEN

               ARGS.CheckNumberOfArguments ( args, 1 ) ;

               RETURN MakeString ( Fmt.Int ( self.value )) ;

          ELSEIF Text.Equal ( selector, "add" ) THEN

               ARGS.CheckNumberOfArguments ( args, 2 ) ;

               RETURN MakeInteger ( GetInteger ( self ) +

                    GetInteger ( Args.Element ( args, 1 ))) ;

          ENDIF

          RAISE Obj.Exception ( Exception.badFunction ) ;

        END IntegerDispatch ;





     Заклинания и dispatching.



     Для  создания  заклинания  клиенты  пользуются    процедурой

Obj.Invoke. Для предыдущего примеры это выглядит примерно так:



     IMPORT Obj ;

     VAR

       a := NEW ( Integer, value := 5 ) ;

       b := NEW ( Integer, value := 4 ) ;

       c := Obj.Invoke ( a, "add", b ) ;





     Командный язык.



     Далее некоторые примеры будут  описаны  на  командной  языке

DOS. Он не является ни неотемлимой частью DOS, ни даже  закончен-

ным языком программирования - это  просто  средство  для  легкого

описания и использования объектов. Предыдущий пример будет  запи-

сан на нем так:



     (DEFINE a 5)

     (DEFINE b 4)

     (DEFINE c (a 'add b))



(мое примечание)

Вообще, командный язык основан на Лиспе; скажем, имеется  функция

LAMBDA.





     Эксперименты с dispatching.



     В этой секции рассказывается о серии экспериментов, призван-

ных обучить dispatching систем. Две цели экспериментов были:

     - показать простой и практически полезный  способ  объедине-

ния различных моделей;

     - найти общие идеи во всех диспетчерах.



     Эксперименты  проводились  с:  Modula-3,  C/C++,   Macintosh

Common Lisp, CLIPS, Sybase, Ontos.





     Dispatching классов.



     В классической модели заклинание интерпретируется как  сооб-

щение, посланное объекту-приемнику. При этом действия  диспетчера

частично определяются его параметрами. Соответственно, при  появ-

лении нового сообщения, программист вынужден добавлять новый  об-

работчик в приемник.

     Классические модели как правило опираются на понятие класса,

выполняющего следующие роли:

     - общий исполняемый код;

     - общий интерфейс;

     - производство новых объектов, разделяющих общие ресурсы.



Типичные характеристики диспетчера классов:

     - каждый объект имеет класс;

     - классы обладают суперклассами, выстраивающимися в иерархию;

     - в ответ на сообщение система ищет в иерархии классов соот-

ветствующий ему обработчик.

     Кроме того, различные системы накладывают на эту схему  свои

специфические ограничения.





     Dispatching родовых функций.



     Иногда полезно рассматривать части заклинания не как  прием-

ник и аргументы. Hапример:



     (aShape 'draw aDevice)



В этом случае конкретный исполняемый код  зависит  не  только  от

aShape, но и от aDevice. Здесь вместо  тупого  выстраивания  кон-

струкции типа case целесообразно воспользоваться техникой кратно-

го dispatching. В классической  модели  единственно  определяющим

аргументом является сообщение;  соответственно,  разумно  объеди-

нить сообщение draw, посылаемое aDevice с  различными  вариантами

aShape, например, drawRectangle. Это решение делает проблему  вы-

бора скрытой от диспетчера.

     Соответствующий механизм называется родовыми функциями.  Это

группа методов, обеспечивающих сходную функциональность над  мно-

жеством классов. draw есть родовая функция, описываемая как



     (defgeneric draw (aShape, aDevice))

     (defmethod  draw (aShape Rectangle) (aDevice X-Window) ... )

     ...



     В DOS для реализации такого подхода требуется описание  спе-

циального объекта - родовой функции; ее задача заключается в "ре-

гистрации" соответствующих частных методов;  получив  заклинание,

диспетчер родовой функции направляет его тому или иному методу  в

зависимости от параметров. Hа языке DOS это описывается так:



     (DEFINE draw

       (GENERIC-FUNCTION (shape device))



     (ADD-METHOD draw (shape device)

       (AND (is-rectangle shape) (is-X-Window device))

       ...

     )

     ...



Так как мы не вправе пользоваться никакой предопределенной инфор-

мацией  об  объектах,  нам   потребуется    дополнить    средства

dispatching возможностью проверить принадлежность объекта  классу

и способность класса к выполнению конкретного заклинания.





     Распределенные объекты.



     Обмен сообщениями между компонентами распределенной по  сети

системы благодаря гибкому dispatching может быть реализован с по-

мощью удаленных заклинаний не меняя базовой концепции DOS.





     Модель клиент-сервер.



     Данная модель совмещается с идеологией DOS  следующим  обра-

зом: клиент заклинает удаленный сервер (приемник). Hеобходимо вы-

полнить две вещи:

     - расширить локальное понятие dispatching для  вызова  через

       сеть

     - построить объект, представляющий образ  сервера  в  клиен-

       тской системе.



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

     - установить связь с сервером

     - перевести аргументы в допустимую для передачи форму

     - послать сообщение серверу

     - ждать ответа

     - перевести ответ сервера в формат локальной системы

     - закрыть соединение

     - вернуть ответ.



Подобный объект-образ должен инкапсулировать в  себе  информацию,

достаточную для связи с сервером; таким образом, он отбирает "се-

тевую" часть диспетчеризации у клиента. Hапример, в  TCP/IP  этот

объект описывается как



     TYPE NetObj = Obj.T OBJECT

          hostname : TEXT ;

          portnum  : CARDINAL ;

     OVERRIDES

          dispatcher := NetObjDispatcher ;

     END



Подобным методом реализуются и другие  сетевые  модели.  Отдельно

следует заметить, что при большом  количестве  объектов  зачастую

целесообразно присвоить им уникальные идентификаторы или индексы,

хранящиеся отдельно от них самих.





     Dispatching объектов в БД.



     В объектно-ориентированных БД  структура  программы  опреде-

ляется сущностью и отношениями неких постоянных объектов. Различ-

ные базы предлагают свои специфические модели  в  зависимости  от

целей вычислений. Проблема  dispatching  этих  объектов  схожа  с

проблемой реализации распределенных систем;  для  поддержания  их

общности мы должны:

     - вынести ссылки на объекты за пределы БД;

     - реализовать  заклинание  над  объектами  с  использованием

       идей dispatching классов и родовых функций.



Для доступа к объектам скорее всего потребуется применять методи-

ку, описанную для распределенных систем.  Важное  отличие  заклю-

чается в том, что для заклинания объектов БД сервер БД и его  об-

раз должны поддерживать сообщение "заклинание". В конкретно изго-

товленной реализации для этого применялось такое средство  объек-

тно-ориентированных БД как динамическое заклинание. Действия сер-

вера БД при получении заклинания:

     - оттранслировать аргументы в рабочий формат;

     - составить из аргументов список и вызвать механизм  динами-

       ческого заклинания для его обработки;

     - вернуть результат как список из значений базовых  типов  и

       идентификаторов объектов.





     Dispatching базы правил.



Традиционно системы работающие с базами правил имеют закрытую ар-

хитектуру и включают в себя интерфейс базы данных,  хранящей  эти

правила. В результате правила оказывают существенное  влияние  на

системные вопросы, такие как база данных и язык программирования.

В этой серии экспериментов авторы пытались понять метод обеспече-

ния гибким dispatching связи между правило- и объектно-ориентиро-

ванными парадигмами.





     Модель базы правил.



     Традиционно системы состоят из двух частей: правил и фактов.

Сердцем системы является процессор правил, использующий правила и

факты для достижения цели. Единственным путем внесения в  систему

данных является декларация фактов. Правда, системы  работающие  с

большими объемами данных, часто объединены с  БД  и  пользователь

может как декларировать факты, так и напрямую работать с таблица-

ми БД.



     Для приведения баз правил к виду объектов мы должны реализо-

вать общий механизм, позволяющий им доступ к внешним данным - се-

тевые заклинания; в частности, это даст БП доступ к удаленным БД.

Теперь БП сама может рассматриваться как распределенный объект.





     Правила как методы объекта.



     Для использования правил в  работе  объекта  следует  просто

реализовать диспетчер, делегирующий работу  процессору  правил  в

соответствии с заклинанием. Вкупе с доступом к  БД  мы  получаем,

что база правил есть объект с состоянием - данными БД и методами -

правилами, также хранящимися в  БД.  Обычно  нежелательно,  чтобы

правила напрямую обращались к БД; соответственно, диспетчер  дол-

жен передавать базе правил свой собственный идентификатор и  про-

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

данным.





     Вынесенные заключения и нерешенные проблемы.



В ходе экспериментов выяснилось следующее:

     - хотя в начальной идее заклинание разбивалось на  адреса  и

аргументы, часто удобно рассматривать заклинание как  неразрывную

сущность;

     - "хорошие" сообщения по идее должны пониматься  всеми  под-

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

щение бессмысленно для принимающего - ответить некоторым стандар-

тно-бессмысленным образом или отдать объекту и позволить ему  об-

работать и/или сгенерировать исключение;

     - возникают вопросы с конкурентным  доступом  к  объектам  в

распределенных системах. В настоящее время идет разработка допол-

нений, которые позволят реализовать любой из  методов  управления

конкуренцией, предлагаемый в прикладных системах;

     - метаобъекты. В системе следует организовать некий  мета-у-

ровень и разрешить доступ к нему диспетчеров. Явное указание  ал-

горитмов диспетчеризации подобно использованию goto: и  гибко,  и

опасно. Постепенно выделятся общие пути диспетчеризации,  которые

станут высокоуровневыми абстракциями;

     - отделение мета- и базового уровня. Смесь в одном диспетче-

ре доступа к обоим уровням трудна для восприятия;

     - оптимизация. Преимуществом предложенной схемы является то,

что она не рассчитана на конкретный метод диспетчеризации и, сле-

довательно, возможно оптимизировать какие-либо  части  работающей

системы не нарушая работы остальных.