[an error occurred while processing this directive]
[an error occurred while processing this directive]

Введение в технологии OLE и ActiveX

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

Можно сказать, что история программирования — это история попыток написать совершенный код. Разработка как прикладного, так и системного программного обеспечения страдала от бесконечных проволочек, а сами программы отличались умопомрачительной сложностью и непредсказуемым количеством “жучков”. И все же без программ не обойтись, но как написать хорошую программу? Для этого нужно обладать способностью соединить общие принципы программного проекта с желанием (и даже горячим стремлением) вникнуть в миллиарды мелочей. Это требует не только колоссальных интеллектуальных усилий, но и соответствующего инструментария, который, увы, все еще далек от совершенства.

ActiveX и OLE фирмы Microsoft — еще один шаг к более совершенным, т.е. более надежным и эффективным, программам. Но не только: “более совершенные” программы должны делать то, что раньше было невозможно, т.е. решать новые проблемы. В основе ActiveX и OLE лежит очень простая идея, но, как оказалось, она позволяет существенно повысить эффективность программирования.

От OLE к ActiveX

Первоначально OLE была задумана как технология интеграции программных продуктов, входящих в комплект Microsoft Office. Предшественницей OLE является реализованная в Windows технология динамического обмена данными DDE (Dynamic Data Exchange), до сих пор широко применяемая в данной среде. Однако многие разработчики не без оснований считают, что DDE трудно использовать, поскольку это технология низкого уровня. По существу, DDE представляет собой модель взаимодействия процессов - протокол, с помощью которого приложение может организовать канал обмена данными с DDE-сервером, находящимся на той же машине. DDE - это асинхронный протокол. Иными словами, после установления связи вызывающая сторона передает запрос и ожидает возврата результатов. Такой механизм более сложен, чем синхронный вызов функции, так как нужно учитывать вероятность нарушения связи, тайм- ауты и другие ошибки, которые приложение должно распознавать и исправлять. Низкая популярность DDE вынуждала Microsoft искать различные способы его усовершенствования. Для упрощения наиболее сложных аспектов протокола была предложена спецификация DDEML, но этого оказалось недостаточно.

Несмотря на различия между низкоуровневой технологией системных объектов и средствами интеграции компонентов высокого уровня, Microsoft попыталась предоставить разработчикам объединенное решение. В качестве технологии более высокого уровня была реализована OLE 1.0 OLE 1 (Object Linking and Embedding — связывание и внедрение объектов). Она расширила возможности протокола DDE и, используя его как базовый механизм коммуникаций, позволила активизировать встроенный объект в документе, т. е. получить составной документ. Таким образом, OLE 1.0 унаследовала многие проблемы асинхронного протокола. Эта технология имела множество недостатков, а ее компоновка была слишком сложна для пользователей среднего уровня. Кроме того, установленные связи легко нарушались, например, в результате изменения маршрута доступа к файлу связанного объекта.

Первое воплощение OLE — OLE 1 — представляло собой механизм создания и работы с составными документами (compound documents). С точки зрения пользователя, составной документ выглядит единым набором информации, но фактически содержит элементы, созданные двумя или несколькими разными приложениями. С помощью OLE 1 пользователь мог, например, объединить электронную таблицу, созданную Microsoft Excel, с текстовым документом “производства” Microsoft Word. Идея состояла в том, чтобы документо-ориентированная (document-centric) модель работы с компьютером позволила бы пользователю больше думать об информации и меньше — о приложениях, ее обрабатывающих. Как следует из слов “связывание и внедрение”, составные документы можно создать, либо связав два разных документа, либо полностью внедрив один документ в другой.

OLE 1, как и большинство первых версий программных продуктов, была несовершенна. Архитекторам следующей версии предстояло улучшить первоначальный проект. Вскоре они поняли, что составные документы — лишь частный случай более общей проблемы: как разные программные компоненты должны предоставлять друг другу сервисы? Для решения этой проблемы архитекторы OLE создали группу технологий, область применения которых гораздо шире составных документов. Основу OLE 2 составляет важнейшая из этих технологий — Модель многокомпонентных объектов (Component Object Model — СОМ). Новая версия OLE не только обеспечивает поддержку составных документов лучше, чем первая, но и несомненно идет куда дальше простого объединения документов, созданных в разных приложениях. OLE 2 позволяет по-новому взглянуть на взаимодействие любых типов программ.

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

Благодаря этим преимуществам, СОМ скоро стал частью технологий, не имеющих никакого отношения к составным документам. Однако в Microsoft хотели сохранить общее имя для всей группы технологий, в основе которых лежит СОМ. Компания решила сократить название Object Linking and Embedding до OLE — эта комбинация более не рассматривалась как аббревиатура — и опустить номер версии.

В начале 1996 года Microsoft ввела в оборот новый термин — ActiveX. Сначала он относился к технологиям, связанным с Интернетом, и приложениям, выросшим из него, вроде WWW (World Wide Web). Поскольку большинство разработок Microsoft в данной области было основано на СОМ, то и ActiveX была непосредственно связана с OLE. Однако очень скоро новый термин стал захватывать территории, традиционно принадлежавшие OLE, и вот теперь все вернулось на круги своя: OLE, как встарь, обозначает только технологию создания составных документов связыванием и внедрением, а разнообразные технологии на основе СОМ, ранее объединенные под именем OLE, собраны под знаменем ActiveX. А некоторые технологии, название которых содержало слово "OLE" даже перекрестили: теперь это технологии ActiveX. Новые технологии на основе СОМ, которым раньше полагался ярлык "OLE", теперь частенько получают пометку "ActiveX".

Понятие СОМ

Все технологии OLE и ActiveX, описанные ниже, построены на основании, обеспеченном СОМ. Итак, что же такое СОМ? Чтобы ответить на этот вопрос, зададимся сначала другим: "Каким образом одна часть программного обеспечения должна получать доступ к сервисам, предоставляемым другой частью? " На сегодняшний день ответ зависит от того, что представляют собой эти части:

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

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

Как работает СОМ

В СОМ любая часть программного обеспечения реализует свои сервисы как один или несколько объектов СОМ (не следует путать объекты СОМ с объектами в языках программирования типа C++; несмотря на то, что у них есть общие черты, это разные вещи; далее будет описано соотношение объектов СОМ и объектов других видов.). Каждый такой объект поддерживает один или несколько интерфейсов, состоящих из методов. Метод — это функция или процедура, которая выполняет некоторое действие и может быть вызвана программным обеспечением, использующим данный объект (клиентом объекта). Методы, составляющие каждый из интерфейсов, обычно определенным образом взаимосвязаны. Клиенты могут получить доступ к сервисам объекта СОМ только через вызовы методов интерфейсов объекта — у них нет непосредственного доступа к данным объекта.

Представим себе, например, корректор орфографии, реализованный в виде объекта СОМ. Такой объект может поддерживать интерфейс, включающий методы типа “НайтиСлово” (LookUpWord), “ДобавитьКСловарю” (AddToDictionary) и “УдалитьИзСловаря” (RemoveFromDictionary). Если позднее разработчик объекта СОМ захочет добавить к этому объекту поддержку словаря синонимов, то объекту потребуется еще один интерфейс, возможно, с единственным методом, вроде “НайтиСиноним” (ReturnSynonym). Методы каждого из интерфейсов сообща предоставляют связанные друг с другом сервисы: либо корректировку правописания, либо доступ к словарю синонимов.

Большинство объектов СОМ поддерживают более одного интерфейса. Сам объект всегда реализуется внутри некоторого сервеpa. Сервер может быть либо динамически подключаемой библиотекой (DLL), подгружаемой во время работы приложения, либо отдельным самостоятельным процессом.

Чтобы вызывать методы интерфейса объекта СОМ, клиент должен получить указатель на этот интерфейс. Обычно СОМ-объект предоставляет свои сервисы посредством нескольких интерфейсов, и клиенту требуется отдельный указатель для каждого интерфейса, методы которого он намерен вызывать. Например, клиенту нашего простого объекта СОМ понадобился бы один указатель интерфейса для вызова методов интерфейса корректора орфографии и другой — для вызова методов интерфейса словаря синонимов.

Любой СОМ-объект — это экземпляр определенного класса. Объекты одного класса могут, например, реализовывать сервисы корректировки орфографии и словаря синонимов, тогда как объекты другого класса — представлять банковские счета. Обычно знать класс объекта необходимо для запуска экземпляра этого объекта, выполняемого с помощью библиотеки СОМ. Эта библиотека присутствует на любой системе, поддерживающей СОМ, и имеет доступ к справочнику всех доступных на данной машине классов СОМ-объектов. Клиент может, например, вызвать функцию библиотеки СОМ, передав ей класс нужного ему СОМ-объекта и задав один из поддерживаемых объектом интерфейсов, указатель которого нужен клиенту в первую очередь. (Эти сервисы реализованы библиотекой СОМ в виде обычных вызовов функций, а не через методы интерфейса СОМ.) Затем библиотека СОМ запускает сервер, реализующий объекты данного класса. Кроме того, библиотека возвращает клиенту указатель требуемого интерфейса вновь созданного экземпляра объекта. Далее клиент может запросить указатели на другие необходимые ему интерфейсы непосредственно у самого объекта.

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

Благодаря СОМ, клиентам нет нужды учитывать данные отличия — доступ ко всему осуществляется единообразно. Для доступа к сервисам, предоставляемым любыми типами программного обеспечения, используется одна общая модель.

СОМ и объектно-ориентированный подход

Объекты — центральная идея СОМ. Но определение и использование объектов здесь иногда отличается от других популярных объектных технологий. Чтобы понять соотношение СОМ и других объектно-ориентированных технологий, следует разобраться, что обычно стоит за термином “объектно-ориентированный” и как СОМ этому соответствует.

Определение объекта

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

До этого места СОМ-объекты именно таковы. Но в большинстве объектных технологий объект поддерживает только один интерфейс с одним набором методов. А вот СОМ-объекты могут — и почти всегда это делают — поддерживать более одного интерфейса. Например, у С++-объекта лишь один интерфейс, включающий в себя все методы объекта. СОМ-объект с его несколькими интерфейсами может быть отлично реализован с несколькими объектами C++ — по одному на каждый интерфейс СОМ-объекта (хотя C++ — не единственный язык, который можно использовать для создания СОМ-объектов; cледует отметить, что, подобно объектам СОМ, объекты языка программирования Java также могут иметь несколько интерфейсов, фактически, Java отлично подходит и для создания СОМ-объектов другими способами.).

Еще одна распространенная концепция в объектно-ориентированной технологии — понятие класса. Скажем, все объекты, представляющие банковские счета, можно отнести к одному классу. Любой конкретный объект “банковский счет”, например, представляющий счет, является экземпляром данного класса.

СОМ-объекты имеют и классы. Класс в СОМ понимается как конкретная реализация набора интерфейсов. Может существовать несколько разных реализации одного и того же набора интерфейсов, каждая из которых будет отдельным классом. С точки зрения клиента, только интерфейсы имеют значение. Клиента не касается реализация интерфейсов, т.е. то, что фактически определяет класс. Возможность работать с объектами разных типов, каждый из которых поддерживает данный набор интерфейсов, но реализует их по-разному, называется полиморфизмом.

Инкапсуляция, полиморфизм и наследование

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

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

C++ предоставляет непосредственную поддержку инкапсуляции (впрочем, и способы ее обойти). В случае некорректной попытки непосредственно модифицировать данные объекта компилятор может выдать программисту сообщение об ошибке. Хотя СОМ и не является языком программирования, идея остается той же самой. Клиент имеет доступ к данным объекта СОМ только через методы интерфейсов этого объекта. Данные объекта СОМ инкапсулированы.

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

Однако фактическая реализация этих двух методов может быть абсолютно разной. Реализация для сберегательного счета может просто сравнить снимаемую сумму с остатком на счете. Если изъятие меньше остатка, операция выполняется, в противном случае — нет. С другой стороны, метод Withdrawal для расчетного счета может быть сложнее. Обычно расчетные счета допускают некоторый объем автоматического кредитования, если сумма чека превышает остаток. Реализация метода Withdrawal для объекта — расчетного счета могла бы сравнивать сумму чека как с текущим остатком счета, так и с максимально допустимым размером кредита. В данном случае запрос отрабатывается успешно, и чек принимается к оплате, если его сумма меньше суммы текущего остатка и максимального размера кредита.

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

Эту идею реализуют в полной мере СОМ-объекты. Объекты двух разных классов вполне могут предоставлять своим клиентам одинаковый набор интерфейсов или, может быть, только одно общее определение метода, даже если каждый объект реализует соответствующие методы по-своему.

Последняя определяющая характеристика традиционных объектно-ориентированных технологий — наследование. Идея проста: имея некоторый объект, можно создать новый, автоматически поддерживающий все или некоторые “способности” старого. Подобно тому, как человек без каких-либо усилий со своей стороны может унаследовать от своих родителей какие-либо признаки, так и объект может автоматически получать характеристики другого объекта.

Виды наследования бывают разные. Следует отметить различия наследования реализации и наследования интерфейса. В первом случае объект наследует от своего родителя код. Когда клиент дочернего объекта вызывает один из унаследованных методов, на самом деле выполняется код метода родителя. Однако в случае наследования интерфейса потомок наследует только определения методов родителя. При вызове клиентом потомка одного из этих методов последний должен самостоятельно предоставить код обработки запроса.

Наследование реализации — это механизм повторного использования кода, широко применяемый в языках типа C++ и Smalltalk. В противоположность этому наследование интерфейса в действительности означает повторное использование спецификации — определений методов, поддерживаемых объектом. Наследования интерфейса облегчает к тому же реализацию полиморфизма. Определение нового интерфейса путем наследования от существующего гарантирует, что объект, поддерживающий новый интерфейс, можно рассматривать как объект, который поддерживает старый интерфейс.

Языки программирования типа C++ и Smalltalk поддерживают как наследование реализации, так и наследование интерфейса. Однако СОМ-объекты поддерживают только наследование интерфейса. Создатели СОМ полагали, что с учетом ее универсальности наследование реализации будет неприемлемым (и даже потенциальной опасным) способом повторного использования одного СОМ-объекта другим. Например, поскольку наследование реализации часто открывает наследующему объекту детали реализации родителя, постольку это может нарушить инкапсуляцию последнего. Поддержка только наследования интерфейса, что имеет место в СОМ, позволяет использовать повторно ключевой элемент другого объекта — его интерфейс — и в то же время избежать указанной выше проблемы.

Но как СОМ-объект повторно использует код другого объекта в отсутствие наследования реализации? Для этого в СОМ имеются механизмы включения (containment) и агрегирования (aggregation). При включении один объект просто вызывает другой по мере надобности для выполнения своих функций. При агрегировании объект представляет один или несколько интерфейсов другого объекта как свои собственные; то, что клиент видит как один объект, предоставляющий группу интерфейсов, на самом деле — два или несколько объектов, агрегированных вместе. Как можно ожидать, реализация агрегирования требует несколько больших усилий, чем включение, но оба механизма — эффективные способы создания надстройки над существующими СОМ-объектами.

Является ли СОМ по-настоящему объектно-ориентированной?

У СОМ много общего с другими объектно-ориентированным технологиями. В ее основе лежит понятие объекта как набора данных и методов, схожее с идеей такого языка, как C++, хотя СОМ и позволяет одному объекту иметь несколько интерфейсов. СОМ также обеспечивает инкапсуляцию, полиморфизм и наследование интерфейсов, однако повторное использование кода в ней осуществляется через включение и агрегирование, а не посредством наследования реализации. Основой СОМ являются объекты, однако способ определения и их поведение несколько отличаются от других распространенных объектно-ориентированных технологий.

Итак, является ли СОМ по-настоящему объектно-ориентированной? Смотря что имеется в виду. Если спрашивается: "Являются ли объекты СОМ в точности такими же, как объекты в языках типа C++? " — ответ однозначно отрицательный. Это не должно слишком удивлять, так как СОМ предназначена для решения совершенно иных проблем, нежели объектно-ориентированные языки программирования. Но если вопрос стоит так: "Предоставляет ли СОМ основные возможности и преимущества объектов? " — то ответ столь же очевидно положительный, и только такая постановка проблемы имеет значение.

СОМ и многокомпонентные программы

За последние 35 лет конструкторы аппаратного обеспечения прошли путь от компьютеров размеров с комнату до маленьких "лэптопов" на основе крошечных, но мощных микропроцессоров. За те же самые 35 лет разработчики программ прошли путь от больших систем на ассемблере и COBOL до создания еще больших систем на С и C++. Это (вероятно) прогресс, но мир программного обеспечения все же развивается медленнее, чем мир “железа”. Что же есть такого у конструкторов аппаратного обеспечения, чего нет у конструкторов программ?

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

Повторное применение — это также путь к созданию лучшего программного обеспечения. Сегодня разработчики программ частенько повторяют дорогу, уже проторенную до них сотнями программистов. Результат часто бывает очень хорошим, но ведь мог бы быть гораздо лучше. Создание новых приложений из существующих, протестированных компонентов, вероятно, должно приводить к более надежному коду. И — что не менее важно — оно может быть гораздо быстрее и дешевле.

Именно этот подход и реализуется в СОМ. Объекты СОМ являются эффективным механизмом применения повторного программного обеспечения, так как позволяют создавать дискретные, повторно используемые компоненты. Эти компоненты, каждый из которых предназначен для выполнения определенной функции, могут играть роль, аналогичную той, что играют различные микросхемы, используемые проектировщиками аппаратуры. Возможно, именно из-за подобной аналогии этот подход стал известен как компонентное программное обеспечение.

Идею трудно назвать новой. Существующие механизмы повторного применения, хотя и важны сами по себе, но не слишком мощны. Чтобы разобраться в этом, рассмотрим две наиболее распространенные схемы повторного применения: библиотеки и объекты.

Как механизм повторного применения, библиотеки могут дать многое. Это особенно верно для динамически подключаемых библиотек, которые могут загружаться по запросу и обычно используются программами совместно, а не компонуются статически с одним приложением. Библиотеки привычны и просты в использовании. Поскольку их можно распространять в двоичной форме, нет риска открыть секреты реализации исходного кода любопытным. Совсем немного усилий, и программа, написанная на одном языке, сможет вызывать из библиотеки процедуры, написанные на другом. Но библиотеки не лишены недостатков. Один из них — сложность расширения функциональных возможностей: как установить новую версию библиотеки и не повредить приложениям, ориентированным на старую? И где простой и легкий способ установить в системе более одной реализации одной и той же библиотеки, что может потребоваться в некоторых обстоятельствах? Библиотечный подход просто недостаточен.

Благодаря инкапсуляции данных и методов, объекты также способны предоставить ясный способ оформления повторно используемых функциональных элементов. Как и традиционные библиотеки, объекты, предназначенные для решения определенных проблем, можно создать только раз и многократно использовать. Но возможности объектов даже больше, чем у библиотек. Наследование позволяет объекту повторно задействовать определение интерфейса другого объекта, или его код, или и то и другое. Полиморфизм упрощает повторное применение, скрывая несущественные различия от клиентов объектов.

Несмотря на все эти преимущества, до максимума потенциальных возможностей объектной технологии по повторному применению программ еще далеко. На пути стоят три основные проблемы.

Первая и, вероятно, самая важная проблема заключается в том, что стандартов для компоновки двоичных объектов в единое целое фактически нет. Хотя можно скомпилировать объект C++ и затем использовать этот скомпилированный объект из библиотеки, это гарантированно сработает, только если и библиотека, и использующее ее приложение скомпилированы одним и тем же компилятором. Для C++ отсутствует стандарт формата двоичных объектов, поддерживаемый всеми компиляторами, поэтому создание и распространение библиотек объектов в лучшем случае проблематично. Вследствие этого доступные сейчас библиотеки объектов C++ практически всегда поставляются с исходным текстом. С этим связана еще одна проблема: повторное использование кода через наследование реализации ведет к тому, что дочерний и родительский объект становятся тесно связанными друг с другом. Создателю дочернего объекта обычно необходим доступ к исходному тексту родительского объекта хотя бы для того, чтобы точно знать, что происходит при вызове наследуемого метода.

Вторая проблема в том, что, несмотря на свои доминирующие позиции в объектно-ориентированной области, C++ — не единственный язык в мире. Объект, написанный на C++, нельзя использовать в программе, написанной, скажем, на Smalltalk, без особых усилий. А что насчет таких инструментов, как PowerBuilder фирмы PowerSoft или Visual Basic фирмы Microsoft? Рынок должен предоставлять объекты, которые могут использоваться разными языками и средами разработки, но пока в приложении, написанном на одном языке, применить объект, написанный на другом, затруднительно.

Третья проблема такова: если создано приложение из объектов, написанных на языке типа C++, и затем решено их изменить один из них, в лучшем случае придется перекомпоновать (relink), а может быть, и перекомпилировать все приложение. Если измененный объект используется несколькими приложениями в системе, все они должны быть перекомпонованы или перекомпилированы. В идеале должна быть возможность так установить новую версию объекта, чтобы все приложения, работающие с ним, переключились на нее автоматически. И, конечно, это должно происходить без перекомпоновки или перекомпиляции любого из этих приложений.

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

СОМ привносит в программирование преимущества технологии всеобщего повторного применения, уже давно “работающей” в области проектирования аппаратуры. В WWW уже существуют узлы, полные компонентов, основанных на СОМ; рекламой компонентов забиты журналы. Рынок объектов становится реальностью — это позволяет программистам создавать продукты, хотя бы частично состоящие из повторно использованных частей. Универсальная архитектура сервисов СОМ применима ко многим задачам, но поддержка создания компонентного программного обеспечения была, возможно, важнейшей целью ее создателей.

Преимущества СОМ

Все, что упрощает сложный процесс создания больших программ, — хорошо. Соглашения, определенные СОМ, достигают этого несколькими путями.

СОМ предоставляет удобный способ структурирования сервисов, предоставляемых разными фрагментами программного обеспечения. Разработчик может вначале организовать проект в виде СОМ-объектов, а затем определить интерфейсы каждого объекта. Это одно из традиционных преимуществ объектно-ориентированного подхода к проектированию. Но СОМ идет дальше, позволяя разработчикам создавать программные компоненты, которые можно распространять и повторно использовать разными путями.

Второе преимущество СОМ — последовательность. Общий подход к созданию всех типов программных сервисов в СОМ упрощает проблемы, с которыми сталкиваются разработчики. Находится ли нужное программное обеспечение в библиотеке, в другом процессе, является ли частью операционной системы, доступ к нему всегда осуществляется единообразно. У последовательности есть и побочный эффект: СОМ сглаживает различия между системным и прикладным программным обеспечением. Если работать со всеми компонентами, как с объектами СОМ, то не чувствуется между этими двумя типами программного обеспечения существенных различий, которые обычно весьма ощутимы. Теперь можно разрабатывать приложения, использующие доступные в данной среде программные сервисы, независимо от того, чем эти сервисы являются и кто их предоставляет.

В дополнение к этому СОМ безразличен язык программирования. СОМ определяет двоичный интерфейс, который должны поддерживать объекты, поэтому объекты СОМ можно создавать на любом языке, способном поддерживать данный интерфейс. Затем обращаться к методам этих объектов можно будет на любом языке, позволяющем осуществлять вызовы данного двоичного интерфейса. Ни объект, ни его клиент не знают — да и зачем им это? — на каком языке написан другой. Правда, некоторые языки лучше подходят СОМ, однако сама по себе СОМ пытается быть независимой от языка.

Еще одно преимущество СОМ вытекает из ее подхода к одной из сложнейших проблем разработки и установки программ — контролю версий (versioning) — т.е. как заменить текущую версию программы на новую, с дополнительными возможностями, не повредив существующим клиентам старой версии? Способность СОМ-объекта поддерживать более одного интерфейса — ключ к решению этой проблемы. Клиент объекта СОМ должен получить указатель нужного ему интерфейса. Дополнительные возможности новой версии объекта можно ввести через новый интерфейс. Старые интерфейсы не изменяются (фактически СОМ запрещает изменение существующих интерфейсов), так что использующие их клиенты не затрагиваются. Причем старые клиенты никогда не запросят указатель на новые интерфейсы. А вот у новых клиентов имеется достаточная информация, чтобы запрашивать новые интерфейсы, реализующие дополнительные возможности; таким образом, новая версия повлияет только на новых клиентов.

СОМ решает и другую сторону этой проблемы — когда клиент ожидает, что объект поддерживает некоторую функциональность, но тот еще не обновлен. Такой клиент запрашивает указатель интерфейса, реализующего новые возможности, но в ответ ничего не получает. СОМ предоставляет ясный способ определить, что объект является не вполне тем, чего ожидает клиент, а потому последний можно написать так, чтобы в этой ситуации он корректно деградировал, а не просто “ломался”. Этот простой и ясный подход, допускающий независимое обновление как клиентов, так и используемых ими объектов, — одно из самых больших достижений СОМ.

Microsoft применяет СОМ в большинстве продуктов; она используется для спецификации расширений Microsoft Windows и Microsoft Windows NT, а также для определения стандартных интерфейсов к различным типам сервисов. Выгоды применения СОМ в разработке всех типов программного обеспечения несомненны.

Доступность СОМ

СОМ разработана Microsoft, а поэтому первоначально была доступна под Windows и Windows NT. Теперь Microsoft предоставляет поддержку СОМ и для Macintosh. Хотя Microsoft не поддерживает СОМ на других операционных системах, этот пробел заполнен третьими фирмами. Несколько компаний — больших и малых — предоставляют реализации СОМ и основанных на ней технологий для широкого диапазона операционных систем. Программное обеспечение, разработанное с применением СОМ-объектов, будет доступно на многих системах — от рабочих станций с Windows и Windows NT до мэйнфреймов IBM, работающих под управлением MVS. И, как Вы увидите далее, Распределенная СОМ (DCOM) позволяет СОМ-объектам на всех типах систем взаимодействовать друг с другом. Возрастающая центральная роль СОМ в программном обеспечении для Windows и Windows NT в сочетании с повсеместным распространением этих систем, подсказывает, что данный новый подход к созданию программ найдет свое применение во всех областях человеческой деятельности.

Обзор технологий ActiveX и OLE

Как OLE, которая теперь снова обозначает только технологии создания составных документов, так и широкий набор технологий под маркой ActiveX, разработаны с использованием СОМ. Многие из этих технологий своими корнями уходят в поддержку составных документов, тогда как другие предназначены совершенно для других целей. Данный раздел содержит краткое введение в наиболее важные технологии СОМ.

Автоматизация

Электронные таблицы, текстовые процессоры и другие программы предоставляют все виды полезных возможностей. Почему бы не обеспечить доступ к ним и другому программному обеспечению? Чтобы это стало возможным, приложения должны предоставлять свои сервисы не только человеку, но и программам — они должны быть программируемыми. Обеспечение программируемости и является целью Автоматизации (Automation, первоначально называвшейся OLE-автоматизацией).

Приложение можно сделать программируемым, обеспечив доступ к его сервисам через обычный СОМ-интерфейс. Однако так поступают редко. Вместо этого доступ к сервисам приложений осуществляется через диспинтерфейсы (dispinterface). Они очень похожи на интерфейсы, (у него есть методы, клиенты осуществляют к нему доступ через указатель интерфейса и т. д.), но имеют и существенные отличия. В частности, методы диспинтерфейса гораздо проще вызывать клиентам, написанным на простых языках типа Visual Basic. Это очень важно: ведь большинство людей, желающих писать программы, осуществляющие доступ к внутренним сервисам приложений, чаще всего выбирают Visual Basic и аналогичные среды.

Чтобы получить представление о возможных выгодах Автоматизации, возьмем, например, Microsoft Excel — программу с широким выбором функций, используемых теми, кто непосредственно работает с Excel. Безусловно, на встроенном в нее макроязыке можно написать целые приложения, использующие функции Excel.

Однако сегодня Microsoft Excel поддерживает Автоматизацию, а это значит, его внутренние сервисы доступны через диспинтерфейсы, поддерживаемые различными СОМ-объектами, предоставляющими методы, скажем, для вычисления среднего значения, проверки правописания и многие другие. Приложения, надстраиваемые над Excel, более не ограничены применением внутреннего макроязыка этой программы, но напротив, могут быть написаны практически на чем угодно. Ныне Excel — не только инструмент для конечных пользователей, но и набор инструментов для разработчиков приложений.

Программируемый доступ к внутренним сервисам посредством Автоматизации поддерживается и рядом других приложений. Именно эта возможность легкого доступа к мощным средствам существующих приложений делает Автоматизацию одной из наиболее широко используемых технологий на основе СОМ.

Перманентность

Объекты состоят из методов и данных, и многим объектам необходимо сохранять свои данные в течение периодов неактивности. На профессиональном жаргоне, объекту необходимо сделать свои данные перманентными (persistent), что обычно означает запись их на диск. СОМ-объекты достигают этого разными путями. Один из наиболее широко применяемых — структурированное хранилище (Structured Storage).

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

Однако в СОМ ситуация сложнее. Так как СОМ обеспечивает совместную работу разных типов программ с помощью одной модели, то независимо разработанный СОМ-объект может стать частью чего-то, что пользователь будет считать одним приложением, и в то же время объекту по-прежнему будет необходимо хранить свои данные на диске отдельно. Каждый СОМ-объект мог бы использовать отдельный файл, но для пользователя приложения объекты невидимы — ведь это одно приложение! — и необходимость следить за большим количеством файлов вряд ли бы ему понравилась.

То, что нам нужно, — это способ совместного использования одного файла несколькими СОМ-объектами. Такую возможность и предоставляет структурированное хранилище. Создавая, по сути дела, файловую систему внутри каждого файла, структурированное хранилище предоставляет каждому компоненту, составляющему некоторое приложение, собственный отдельный кусок пространства хранилища, собственные “файлы”. С точки зрения пользователя, файл только один. Однако с точки зрения приложения, каждый компонент имеет собственную область для хранения данных, и все такие области находятся внутри одного дискового файла.

Чтобы реализовать все это, структурированное хранилище определяет два типа СОМ-объектов, каждый из которых поддерживает соответствующие интерфейсы. Эти объекты известны как хранилища (storage) и потоки (streams) и аналогичны соответственно каталогам и файлам обычной файловой системы. Файл структурированного хранилища может содержать данные многих СОМ-объектов, каждый из которых использует для сохранения своих данных собственное хранилище или поток. Точно так же, как обычная файловая система обеспечивает совместное использование диска несколькими приложениями, структурированное хранилище позволяет разным приложениям сообща использовать один файл.

Однако перманентность — это не только структурированное хранилище. СОМ-объект может сохранять свои перманентные данные и другими способами, например в обычном файле или в WWW. Кроме того, клиенты объекта должны иметь возможность сообщить ему, когда выполнять загрузку и сохранение перманентных данных. Для этого объект может поддерживать один (или несколько) из стандартных интерфейсов, предназначенных для этой цели.

Моникеры

Моникер (moniker, имя, кличка) сам по себе является СОМ-объектом, но весьма специфического назначения: любой моникер знает, как создать и инициализировать экземпляр другого объекта. Например, имея моникер для банковского счета, можно попросить его создать счет, инициализировать его и соединить с ним. Все детали, необходимые для выполнения этих действий, скрыты от клиента. Если он хочет работать посредством моникеров с двумя банковскими счетами, то ему потребуется два отдельных моникера, по одному для каждого объекта — счета. Вообще моникеры в среде СОМ не необходимы; они просто облегчают жизнь клиентов.

Единообразная передача данных и объекты с подключением

Обмен данными — фундаментальная операция в программировании. Например, когда пользователь перемещает данные через буфер обмена (clipboard), приложения осуществляют их копирование. Различные типы системных программ, такие как драйверы, предоставляют информацию о своих устройствах использующим их программам. Учитывая огромное количество поводов для обмена данными между программами, не стоит удивляться, что для этой цели было изобретено сверхбольшое количество схем.

Стандартный способ обмена информацией в мире СОМ — Единообразная передача данных (Uniform Data Transfer). Как и любая технология ActiveX или OLE, использующие его приложения должны поддерживать определенные интерфейсы СОМ. Методы этих интерфейсов определяют стандартные способы для описания передаваемых данных, для указания их местоположения и собственно для их пересылки. Они даже определяют простой механизм, позволяющий одному приложению уведомить другое о том, что нужные последнему данные стали доступны. Хотя Единообразная передача данных вряд ли является самым восхитительным аспектом СОМ, она играет важную роль в работе СОМ-приложений.

Полезная в определенных ситуациях простая схема, определенная Единообразной передачей данных для уведомления клиента о наличии интересующих его данных, не вполне достаточна. Именно для ликвидации этих недостатков на основе СОМ была разработана технология Объектов с подключением (Connectable Objects). Обеспечивая более общий механизм обратной связи объекта с клиентом, Объекты с подключением позволяют клиенту легко получать уведомления об интересующих его событиях.

Составные документы

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

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

Определенный OLE стандартный интерфейс обеспечивает взаимодействие между приложениями любых типов и любых производителей, а не только между электронными таблицами и текстовыми процессорами Microsoft.

При создании составного документа с помощью OLE одно из приложений всегда является контейнером. Как следует из названия, контейнер определяет самый общий документ, в котором содержится все остальное. Другие приложения — серверы могут размещать свои документы внутри документа-контейнера.

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

Управляющие элементы ActiveX

Почему для включения в текстовый документ электронной таблицы необходимо использовать весь Excel? Если нужны только основные возможности электронных таблиц, то вероятно, можно обойтись меньшим, более быстрым и дешевым компонентом. Многим программистам пришлась бы по вкусу возможность построить целое приложение по большей части из готовых компонентов.

Именно подобное желание и привело к идее компонентного программного обеспечения — области, где СОМ способен на очень многое. Повторно применимые компоненты можно создавать на основе исключительно самой СОМ, но для этой цели полезно определить и некоторые стандартные интерфейсы, и соглашения. Используя последние, можно создавать компоненты, единообразно выполняющие такие распространенные задачи, как обеспечение пользовательского интерфейса и посылка сообщений клиенту. Эти стандарты и определяет спецификация управляющих элементов ActiveX (ActiveX Controls).

Управляющий элемент ActiveX — независимый программный компонент, выполняющий специфические задачи стандартным способом. Разработчики могут задействовать один или несколько таких элементов в приложении, чтобы получить преимущества функциональных возможностей существующего программного обеспечения. В результате программное обеспечение построено в основном из уже готовых частей — будет то, что называется компонентным программным обеспечением.

Первоначально управляющие элементы ActiveX были известны под названием управляющие элементы OLE или ОСХ. Microsoft изменила название, чтобы отразить некоторые новые возможности, сделавшие эти элементы более подходящими для Интернета и WWW. Например, управляющий элемент ActiveX может хранить свои данные на странице где-то в WWW либо может быть выкачан с сервера WWW и затем запущен на машине клиента. И контейнер, в котором работает управляющий элемент, не обязан быть средой программирования — вместо этого он может быть средством просмотра WWW.

Управляющие элементы ActiveX — не отдельные приложения. Напротив, они являются серверами, которые подключаются к контейнеру элементов. Как обычно, взаимодействие между управляющим элементом и его контейнером определяется различными интерфейсами, поддерживаемыми СОМ-объектами. Фактически управляющие элементы ActiveX используют многие другие технологии OLE и ActiveX. Например, управляющие элементы обычно поддерживают интерфейсы для внедрения и зачастую предоставляют доступ к своим методам через диспинтерфейсы Автоматизации.

Распределенная СОМ

Хотя СОМ с самого начала разрабатывалась с учетом поддержки распределенных систем, ее первоначальная реализация могла работать только на одном компьютере. Объекты СОМ могли быть реализованы в DLL или в отдельном процессе, исполняемом на той же машине, что и их клиент, но не могли располагаться на других машинах в вычислительной сети. Эта ситуация изменилась с появлением распределенной СОМ (Distributed СОМ — DCOM). Теперь объекты СОМ могут предоставлять свои сервисы и клиентам на других машинах.

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

СОМ и технологии Интернета

Интернет и стиль доступа к данным, обеспечиваемый WWW, обрушились на берега информатики, как цунами. Microsoft не первая осознала влияние, которое может оказать эта волна, но не замедлила с ответом. Не удивительно, что большинство новых технологий Microsoft в данной области созданы с использованием СОМ. Уже говорилось, что ActiveX своим названием обязана встрече СОМ и Интернета, хотя теперь оно и распространилось на многие другие технологии на основе СОМ.

Компонентный подход СОМ находит различные применения в технологиях Microsoft для Интернета и WWW. Например, средство просмотра WWW фирмы Microsoft — Проводник по Интернету (Internet Explorer) — активно использует расширение технологии составных документов OLE — Документы ActiveX (ActiveX Documents). Благодаря этому расширению, пользователь может просматривать информацию разного типа в дополнение к обычным страницам HTML (Hypertext Markup Language — Язык разметки гипертекста). Технология управляющих элементов ActiveX была расширена, чтобы код и данные управляющих элементов могли при необходимости загружаться с сервера WWW и исполняться внутри средства просмотра. Сценарии ActiveX (ActiveX Scripting) — универсальный способ исполнения клиентами сценариев, написанных на любом языке, тогда как технология Гиперсвязей ActiveX (ActiveX Hyper-links), в основе которой лежат моникеры, обеспечивает создание гиперсвязей в стиле WWW на только между страницами HTML, но и между любыми типами документов.

Перспективы ActiveX и OLE

Итак, OLE - это набор стандартов для связи и внедрения объектов при создании компонентов программного обеспечения. Одним из стандартов OLE является спецификация модели составного объекта (или COM), основа для бинарных соединений между компонентами.

Начав скромно, как способ создания составных документов, СОМ развилась в фундаментальную основу прикладного и системного программного обеспечения. СОМ получила такое широкое применение потому, что определяемая ею архитектура предоставления сервисов — привлекательное решение массы проблем. Учитывая ее универсальность и очевидные преимущества, описанные здесь применения СОМ, по всей вероятности, только начало. Хотя общая марка, под которой выступают технологии на основе СОМ, с течением времени изменялась от OLE к ActiveX, с чисто технической точки зрения, это не имеет значения. Дело не в названии, а в тех преимуществах СОМ и ее приложений, что продолжают повсеместно проявляться во всей этой части мира информатики.

OLE позволяет увеличить степень интеграции между программными модулями и служит для создания множества взаимозаменяемых компонентов программного обеспечения. Набор услуг, которые предлагает OLE, не постоянен. Microsoft постоянно модернизирует и расширяет операционную систему Windows, и точно также она готова развивать OLE, чтобы адаптировать к широкому диапазону требованию по интеграции приложений.


[an error occurred while processing this directive]


[an error occurred while processing this directive]