Но в любом случае система должна быть интегрирована и по мере возможности обладать достаточной эффективностью.
Проследим самые важные вехи в процессе обеспечения интероперабельности распределенных программных компонентов. Первым шагом был механизм "программных гнезд" (socket), разработанный в университете Беркли. Он позволял с использованием единого механизма межпроцессных взаимодействий интегрировать программные компоненты, распределенные в локальных или территориально рассредоточенных сетях. Основной недостаток программных гнезд в том, что это чисто транспортный механизм. В частности, представление передаваемых по сети данных машинно-зависимо. Следовательно, в каждом узле сети нужно правильно преобразовывать представление данных, получаемых из любого другого узла.
Следующим шагом стало появление протокола вызова удаленных процедур (Remote Procedure Calls - RPC). В большинстве случаев взаимодействие программных компонентов ассиметрично. Практически всегда можно выделить клиента, которому требуется некоторая услуга, и сервер, который такую услугу способен оказать. Более того, как правило, клиент не может продолжать свое выполнение, пока сервер не произведет требуемые действия. Другими словами, типичное взаимодействие клиента и сервера - процедурное. С точки зрения клиентской программы обращение к серверу ничем не отличается от вызова локальной процедуры. При реализации механизма вызова удаленных процедур на основании спецификации интерфейса процедуры на стороне клиента генерируется локальный представитель удаленной процедуры (stub), а на стороне сервера - специальный переходник (proxy).
В семейство протоколов RPC входит полезный протокол внешнего представления данных (External Data Representation - XDR), специфицирующий машинно-независимое представление данных, понимаемых RPC. При передаче параметров вызова удаленной процедуры и при получении ее ответных параметров происходит двойное преобразование данных сначала из исходного машинно-зависимого формата в формат XDR, а затем в машинно-зависимый целевой формат. Взаимодействующие программы избавлены от необходимости разбираться в деталях. Возможно, именно XDR обладает определяющим значением в связке протоколов вызова удаленных процедур.
Сегодня, видимо, наиболее перспективен подход, специфицированный консорциумом Object Management Group. Опять-таки, основная идея проста. Как бы мы не стремились выработать единые языковые средства для разработки распределенных информационных систем, похоже, это стремление останется среди других благородных, но недостижимых задач человечества. Унификация невозможна. Есть много разных подходов, каждый из которых в чем-то превосходит другие. Нельзя сказать, что какой-то подход является определяющим. Пожалуй, единственное, на чем сходится большинство исследователей, - это склонность к использованию объектной ориентации.
Объектно-ориентированный стиль стимулирует повторное использование программных компонентов (за счет механизма наследования), обеспечивает независимость использования информационных ресурсов от особенностей их реализации (за счет инкапсуляции), наконец, при проектировании и разработке информационных систем позволяет производить комплексную разработку структур данных и управляющих ими процедур.
Все это прекрасно. Но проблема состоит в том, что отсутствует общая объектная модель. В разных объектно-ориентированных системах программирования и системах баз данных гораздо больше общего, чем различного, но их различия часто настолько принципиальны, что объекты, разработанные в разных системах, не способны взаимодействовать. Они не понимают друг друга, они не интероперабельны. А вот это уже очень плохо. В особенности потому, что Internet делает возможным использование информационных ресурсов вне зависимости от их реального расположения.
OMG предлагает ограниченное, но практически достижимое решение этой проблемы. Это общая архитектура Object Management Architecture (OMA) и ее конкретное воплощение Common Object Request Broker Architecture (CORBA). Поскольку сегодня отсутствует объектная модель, которая могла бы служить "общей крышей" для существующих объектно-ориентированных языков и систем программирования, то единственным практическим выходом была выработка минимальной объектной модели, обладающей ограниченными возможностями, но имеющая явные аналоги в наиболее распространенных объектных системах. В архитектуре CORBA минимальную модель называют Core Object Model, и ей соответствует язык спецификации интерфейсов объектов Interface Definition Language.
Чтобы обеспечить возможность взаимодействия объекта, существующего в одной системе программирования, с объектом из другой системы, в исходный текст первого объекта (правильнее сказать, его класса) надо поместить спецификацию на языке IDL интерфейса того объекта, метод которого должен быть вызван. Аналогичную спецификацию надо поместить и на стороне вызываемого объекта. Спецификации обрабатываются соответствующим прекомпилятором IDL (таких прекомпиляторов ровно столько, сколько поддерживается интероперабельных объектных сред; сегодня специфицированы правила встраивания IDL в программы на Си, Си++ и Smalltalk). Спецификация интерфейса представляет собой набор сигнатур методов объекта. В каждой сигнатуре определяется имя метода, список имен и типов данных входных параметров, а также список имен и типов данных результатов выполнения метода. Кроме того, IDL позволяет определять структурные типы данных.
Что является результатом работы прекомпилятора? Все очень похоже на RPC: на стороне клиента генерируется текст объекта-посредника, который играет роль локального представителя удаленного объекта (с ограничениями, свойственными IDL). Работа с ним происходит по правилам соответствующей системы программирования: в среде Си++ - это объект Си++, в среде Smalltalk - объект Smalltalk и т.д. С другой стороны, в генерируемом коде заложены знания о том, что требуется сделать для обращения к методу удаленного объекта.
На стороне сервера генерируется текст объекта sceleton, посредника при доступе к удаленному объекту, который "знает", что обращение является удаленным, и умеет обращаться к удаленному объекту по правилам его системы программирования.
Конечно, для доставки сообщения от клиента к серверу и получения ответных результатов должен существовать полусистемный компонент, отвечающий именно за это. В архитектуре CORBA такой компонент называется брокером объектных заявок (Object Request Broker - ORB). В функции брокера главным образом входит передача данных в машинно-независимом формате от клиента серверу и от сервера клиенту. Кроме того, ORB отвечает за правильное указание сетевого адреса объекта-сервера.
Принимаемые OMG документы исключительно авторитетны и становятся фактическими стандартами. Проблемой же CORBA была нестандартизованность взаимодействий уровня ORB-ORB. В результате брокеры, производимые разными компаниями, не могли совместно работать. Теперь уже они не понимали друг друга. В прошлом году принят новый стандарт CORBA-2, который специфицирует протокол взаимодействий между брокерами. Реализации этого протокола уже появились, есть надежда, что информационные ресурсы Internet станут доступнее. Дай-то Бог!
Конечно, CORBA - это далеко не все, что требуется. Следующая ужасно сложная и непонятная тема - семантическая интероперабельность объектных систем.
Сергей Кузнецов - главный редактор журнала "Открытые системы". С ним можно связаться по телефону (095) 932-9212.