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

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

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

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

"Прятки". Как узнать компонент?

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

Итак, два самых ярких признака компонента:

  • объединяет данные и действия с ними (методы), что позволяет говорить о его родственном сходстве с объектом в объектно-ориентированных языках программирования;
  • является независимым от программной среды, операционной системы, сетевой инфраструктуры (в отличие от объекта).

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

Единый подход к мнемоническому описанию компонентов еще не сформировался, и поэтому естественно использовать средства моделирования бизнес-процессов. Наиболее популярны дополненные структурой данных привычные алгоритмические блок-схемы, IDEF-диаграммы (ICAM Definition - интегрированный язык машинного моделирования технологическиx операций, компьютерных систем и баз данных, основанный на принципе декомпозиции) или UML-схемы (Unified Modelling Language - унифицированный язык наглядного моделирования программных систем). Упомянутые языки функционального моделирования не слишком хорошо известны. Представление о них можно получить, сравнивая описания одного и того же компонента, приведенные на рис. 1.

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

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

Чтобы лучше понять, что такое компоненты, можно попытаться представить их как n-мерные многогранные детали конструктора программных приложений, где на всех или только некоторых гранях расположены интерфейсы - пазы и выступы. С помощью последних можно соединять компоненты, создавая многофункциональные модели. Попытки объединения простых действий в сложные операции, а также использование готовых решений, конечно, не является революционно-новым и в информационных технологиях. Самый "старый" пример - контейнер связанных символом "|" команд UNIX (механизм pipe), когда выход одной команды-компонента передается на вход другой, а самые модные - гибкие, настраиваемые JavaBeans-объекты, которые могут динамически загружаться с помощью специальной программы, и компоненты ActiveX. Наиболее распространенная компонентная технология - динамические библиотеки (DLL). Полностью отвечают определению компонентов CORBA-объекты. Не поддерживают независимость от языка Java-аплеты.

Одна из сложнейших и важнейших задач при работе с компонентами - построение связующей и управляющей среды, которую по аналогии с СУБД можно ласково назвать СУРКом - системой управления распределенными компонентами. Ее основная обязанность - обеспечивать динамическое слияние компонентов. Кроме того, именно она подходит для выполнения таких необходимых сервисных услуг, как синхронизация транзакций, охрана безопасности, отслеживание версий, ведение документальных файлов (логирование) и многих других. Простейшая система управления компонентами - уже упоминавшиеся оболочки в ОС UNIX (sh, ksh, csh). В настоящее время в качестве СУРКа можно использовать, например, мониторы транзакций (Tuxedo) или брокеры объектных запросов (Visibroker фирмы Inprise или Orbix фирмы Iona Technologies). Эти достаточно развитые средства предоставляют широкий круг дополнительных возможностей, а именно: службы ведения уникальных и групповых наименований в распределенной среде, поддержку двухфазного подтверждения транзакций, отслеживание событий по подписке.

Любимое место, куда прячутся компоненты, - репозитарий. Из этого хранилища их можно извлекать по мере необходимости. Как мы берем в библиотеке заинтересовавшие нас книги, так и подходящие компоненты достаем из репозитария и используем в приложении. Единственная проблема - как отыскать то, что нам требуется. Но если в библиотечном деле существуют службы каталогов, позволяющие найти нужный том, то в хранилище компонентов, напротив, царит полная анархия. Например, CORBA предлагает пять различных вариантов конструирования наименований. Ниже приведены наиболее популярные модели построения компонентных имен.

  • Библиотечная. Основана на комбинации уникального идентификатора фирмы-производителя (например, URL), внутреннего имени компонента и номера версии. Название указывает на параллель с книжным делом (автор - заглавие - год выпуска).
  • Функциональная. Представляет компонент кратким описанием возложенных на него обязанностей, в частности - его методов. Уникальность имени в этом случае сомнительна. Описать функциональность словами не всегда возможно.
  • Атрибутная. Компонент именуется по данным, с которыми работает. Это может быть структура данных в виде, например, доменов.
  • По ключевым словам. В некоторых организациях разработана система перечисляемых переменных, сочетание которых образует имя компонента.
  • По местоположению. По физическим адресам на диске.

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

В заключение "пряток" попробуем определиться с бизнес-объектом, распределенным объектом и компонентом. Бизнес-объект - полномочный представитель последнего в бизнес-приложении. Проделавший всю техническую работу, компонент в готовом, собранном приложении уже не виден. А конечный пользователь, работающий с приложением, не интересуется компонентами - он использует подходящий бизнес-объект, не задумываясь, каким образом он реализован. Распределенный объект по терминологии OMG по сути является компонентом, поддерживающим соответствующие стандарты CORBA и живущим в сетевой инфраструктуре.

"Салочки". Взаимодействие компонентов

Один компонент может "осалить" другой различными способами. Наиболее популярные и изученные из них приведены в табл. 1.

Для того чтобы компоненты одной компании-производителя умели общаться с собратьями другого разработчика, они должны соответствовать одному или обоим из ныне существующих наборов стандартов: CORBA и COM/DCOM. В первом случае взаимодействие компонентов осуществляется через специальную интеллектуальную шину ORB (Object Request Broker - брокер объектных запросов), представляющую собой набор демонов и динамических библиотек.

Для обеспечения универсальности достаточно соответствовать одному из стандартов, поскольку уже созданы мосты между ними.

"Считалочки". Алгебраические игры

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

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

Параллельно построим соответствующие функциональные уровни для методов (действий, операций).

  • Множество методов. Каждый метод, используя подходящее информационное множество первого уровня, дает один определенный результат.
  • Множество определений методов. Алгоритм работы. Требует множество данных второго уровня.
  • Множество методов, возможно связанных определенными достаточно сложными взаимоотношениями над информационным множеством третьего уровня (собственной базой данных).

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



Рис. 3 "Пустой" и "полный" компоненты

Несколько замечаний относительно множества компонентов. Интересно рассмотреть крайние случаи: компонент, не содержащий данные, и компонент, состоящий только из данных. Понятно, что для полноты рассмотрения оба случая должны присутствовать. К первому подходит, например, довольно бессмысленный компонент выключения (shutdown) клиентского места. Ко второму - совершенно непригодный для использования "закрытый" компонент, чьи данные нельзя даже извлечь. Отметим также пустой компонент, не содержащий ни действий, ни данных, и компонент, совпадающий с приложением (рис. 3).

Приведем традиционный набор операций над компонентами и проверим некоторые полезные свойства.

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

Из определения очевидно, что сложение компонентов подчиняется следующим свойствам:

  • коммутативность. A + B = B + A;
  • ассоциативность. A + (B + C) = (A +B) +C;
  • A + 0 = A

Умножение. Компонент A называется произведением компонентов B и C, если функциональные и информационные множества всех уровней являются пересечениями соответствующих множеств компонента B и компонента C.

Выполняются свойства:

  • коммутативность. AB=BA;
  • ассоциативность. (AB)C=A(BC);
  • AA=A

Перечислим специальные операции для компонентов.

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

Встраивание - поглощение. Один компонент становится элементом данных другого. Это так называемая концепция контейнеров, пример ее - технология OLE.

Выталкивание - обратная встраиванию операция.

Ключи от форта Байярд

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

Компоненты, как интеллектуальные особы, вполне способны к самообучению и приспособлению к необычным ситуациям.

Подкидной дурак

Никуда не уйти от печального утверждения, что современные "монолитные" приложения достигли столь гигантских размеров и такого функционального многоцветья, что разобраться в них даже искушенному профессионалу стало очень непросто. Именно неподъемная сложность компьютерных систем и подтолкнула разработчиков к новой компонентной концепции. Если мы сейчас у истоков всеобщей компонентизации, то существует здоровая надежда на блаженное упрощение как разработки, так и внедрения, обучения, адаптации и самого использования систем нового типа. Вполне возможно, что работать с ними будет не труднее, чем сыграть в популярнейшую и простейшую карточную игру. Принцип KISS (поцелуй, англ. ) - "Keep it simple, stupid!" (Упрощай, дурак!) становится все более любимым и прекрасно подходит для компонентов.

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

Вместо заключения

На сладкое: "Кто на свете всех белее, всех приятней и милее?" Почему сборная компонентов побеждает в большинстве командных игр? Несколько ответов приведено в табл. 2.

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

В заключение хочу извиниться за явное предпочтение "пряток" и "салочек" в выбранных играх. Это связано как с молодостью самих компонентов, так и с личными пристрастиями автора. n

ОБ АВТОРЕ

Марина Аншина - руководитель сектора разработок и системной поддержки фирмы "ТопС", тел.: (095) 253-63-18, marinaa@tops-msk.com

Литература

  1. Edwards J., DeVoe D. 3-Tier Client/Server at work. 1997.
  2. Ring K., Ward-Dutton N. Componentware: Building it, Buying it, Selling it. Ovum, 1998.
  3. Unified Modelling Language version 1.1. Rational Software Corporation. 1997.
  4. Jacobson I. Object-oriented software engineering. Reading, Massachusetts. Addison-Wesley, 1992.
  5. Eeles P., Sims O. Building Business Objects. John Wiley & Sons, 1998.
  6. Offali R., Harkey D., Edwards J. Essential Distributed Objects Survival Guide. Wiley, 1996.
  7. Offali R., Harkey D., Edwards J. Instant CORBA. Wiley,1997.
  8. Baker S. Corba Distributed Objects: Using Orbix. 1997.
  9. Дейт К. Дж. Введение в системы баз данных. 1998.


Таблица 1.
Метод общенияОписаниеПримеры
РазговорМножественные длительные взаимодействия между компонентами по выделенной линии связиTCP/IP сокеты, CPI-C (IBM)
Запрос - ответЕдиничное взаимодействие между компонентамиRPC- и ORB-вызов удаленного метода
ОчередиСвязь между компонентами не напрямую; сообщения от них помещаются в очередь. Способы обработки очередей сообщений могут быть основаны на различных принципах: по приоритетам, прямой или обратный стекMOM (Message Oriented Middleware) и мониторы транзакций
Подписка и уведомлениеПодписка одних компонентов на некоторые события других и получение соответствующих извещенийСервис событий CORBA, сервис событий монитора транзакций
Широковещательные запросы и дайтаграммыУстановление однонаправленной связи с одним или несколькими компонентамиОднонаправленные вызовы CORBA и специальные сервисы монитора транзакций
Вызов удаленных процедур (RPC)Вызов одним компонентом процедуры на другомDCE, RPC
Передача объекта по значениюПри запросе объектом-клиентом метода на объекте-сервере, вместо загрузки метода на свой узел, объект-клиент передает собственное значение на узел, содержащий объект-сервер, где оно и обрабатывается соответствующим методомJava RMI (Remote Method Invocation) и CORBA передача объекта по значению

Таблица 2
Новые возможностиПреимущества для разработчиковПреимущества для пользователейПреимущества для системных интеграторов и консультантов
Создание приложений разбивается на отдельные независимые шаги по созданию компонентов Разработка становится легко управлямым процессом. Повышается качество и упрощается процессДозаказ и доработка компонентов не зависят от авторов приложенияПроцесс внедрения становится параллельным процессу разработки
Можно использовать уже готовые компоненты, перенося их из приложения в приложениеУменьшается время разработки и ее себестоимость"Любимые", привычные компоненты можно использовать наряду с усовершенствованнымиТакие компании становятся "хранителями" компонентов, их роль возрастает, они позволяют ориентироваться в многообразии рынка
Возможность совмещать в одном приложении компоненты разных версийПлавное развитие приложений в ритме изменения запросов пользователейИзменение только тех компонентов, которые действительно должны быть замененыЛегкость обновления программного обеспечения
Повышается гибкость приложения, которое просто собирается из компонентовПроизводители программного обеспечения могут сконцентрироваться на создании компонентов определенной функциональностиВ одном приложении можно совмещать компоненты разных производителей, которые наилучшим образом решают задачи предприятияУменьшаются время и цена внедрения
Естественная гибкость полномочий пользователейОбеспечение безопасности приложения становится проще и нагляднейБезопасность на основе разрешения, а не запрещения. Заказчик имеет доступ только к тем компонентам, с которыми должен работатьПостроение схемы безопасности конкретной реализации системы исходя из требований определенного заказчика
Простой способ дублировать функциональностьНе надо разрабатывать сложный механизм дублированияОтсутствие избыточности, дублируются только необходимые компоненты Повышение надежности собранной системы
Естественная поддержка распределенной архитектурыСнижаются затраты на реализацию многоуровневой архитектуры приложенияРавномерное распределение нагрузки по сети и уменьшение сетевых сбоевПростота внедрения
Компонент является отдельной торговой единицейМодернизация маркетинговой политикиМожно модернизировать системы постепенноВозможность постепенного, плавного освоения новых технологий