Композиционная адаптация позволяет программному обеспечению динамически менять свои структуру и поведение в ответ на изменения окружающей среды. Мы рассмотрим подходы к реализации композиционной адаптации программ и расскажем о том, как, когда и где происходит такая реорганизация.
За последние несколько лет значительно возрос интерес к адаптивным компьютерным системам. Создан целый ряд подходов, позволяющих программному обеспечению динамически адаптироваться к окружающей среде. Их формирование во многом обусловлено поистине революционными изменениями в ИТ-отрасли.
Во-первых, это распространение повсеместных вычислений (ubiquitous computing), способствующих устранению традиционных границ, определяющих, как, когда и где взаимодействуют человек и компьютер [1]. Например, мобильные устройства должны адаптироваться к разным условиям работы беспроводных сетей и экономить ограниченный заряд батарейки.
Во-вторых, рост спроса на самоуправляемые вычисления (autonomic computing), способные себя защищать и требующие вмешательства человека лишь на самом верхнем уровне [2]. Это особенно важно для финансовых и энергосистем, которые должны сохранять работоспособность при любых сбоях оборудования и любых попытках взлома защиты.
Можно выделить два основных подхода к адаптации программного обеспечения. Параметрическая адаптация подразумевает изменение переменных, определяющих поведение программы. Самый известный пример реализации такого подхода — протокол TCP, чье поведение меняется за счет модификации значений, влияющих на управление окнами передачи и ретрансляцией в случае перегрузки в сети. Но параметрическая адаптация имеет серьезный недостаток: она не позволяет добавлять новые алгоритмы и компоненты к приложению после завершения его проектирования. При таком подходе можно менять параметры или заставить приложение следовать какой-либо иной из имеющихся стратегий, но добавлять новые стратегии нельзя.
В свою очередь, композиционная адаптация предполагает замену каких-либо алгоритмических или структурных компонентов программы другими, позволяющими этой программе быть адекватной конкретным условиям ее рабочей среды. Приложение способно использовать новые алгоритмы для решения задач, которые не ставились при его разработке. Благодаря композиционной адаптации можно выполнять динамическую реорганизацию ПО во время его исполнения — например, чтобы разместить компоненты программы, изъять их из устройства с ограниченной емкостью памяти либо обеспечить новые функции в уже установленных системах.
Динамическая реорганизация программ впервые была реализована еще на заре компьютерной эры. Тогда самомодифицирующийся код поддерживал оптимизацию программы во время ее исполнения и прямое управление физической памятью, но отлаживать подобные программы было очень сложно. Сегодня появился ряд технологий, которые помогают решать возникающие при этом проблемы. Рассмотрим такие технологии, предлагаемые решения и направления дальнейших исследований.
Имеющиеся технологии
Основу всех подходов к композиционной адаптации составляет некоторый промежуточный слой, используемый для «перехвата» и «перенаправления» взаимодействий между элементами программы. На рис. 1 представлены три технологии — выделение задач, вычислительная рефлексия и компонентный дизайн. Мы считаем их основой для проектирования программного обеспечения, допускающего рекомпозицию. Программисты могут применять их для создания самонастраивающихся систем, конфигурация которых меняется систематически на основе определенных принципов, а не только в особых случаях [3].
Рис. 1. Основные технологии, поддерживающие композиционную адаптацию |
Выделение задач
Выделение задач (separation of concerns) позволяет размежевать функциональное поведение приложения (т.е. его бизнес-логику) и код, призванный реализовать общие задачи (такие, как обеспечение гарантированного качества обслуживания, снижение энергопотребления, повышение уровня отказоустойчивости и безопасности [4]). При этом локальная реализация решения общей задачи невозможна: требуемый код приходится добавлять в разные места программы. Отделение общих задач от бизнес-логики упрощает разработку и обслуживание программ, делает более реальным их повторное использование.
Выделение задач стало важным принципом программной инженерии [5]. Сейчас, по-видимому, наиболее распространенным подходом является аспектно-ориентированное программирование [6], которое предлагает методы формирования абстракций и языковые конструкции для решения общих задач, называемых аспектами (aspects). Код, реализующий решение этих задач, разрабатывается независимо от остальных частей системы. В аспектно-ориентированном программировании точки врезки (pointcuts) — это набор позиций кода, на которых разработчик может интегрировать аспекты.
Как правило, точки врезки задаются во время разработки. Позже (скажем, во время компиляции) разработчик с помощью специального компилятора, называемого интегратором аспектов (aspect weaver), связывает аспекты с бизнес-логикой приложения и создает программу с новым поведением. Пример такого решения — компилятор AspectJ. Сторонники данного подхода утверждают, что выделение общих задач позволяет существенно упростить разработку программ, их поддержку и развитие.
Широкий спектр проблем, которые призвана решить адаптация, связан с общими задачами (скажем, с обеспечением гарантированного качества обслуживания). Аспектно-ориентированное программирование играет важную роль в динамической рекомпозиции, поскольку позволяет изолировать задачи общего характера от остальной части программы. Однако при традиционном аспектно-ориентированном подходе скомпилированная программа остается сложной. Для воплощения динамической реорганизации программисту необходимы средства, обеспечивающие разделение задач и во время их исполнения.
Вычислительная рефлексия
Под вычислительной рефлексией (computational reflection) понимается способность программы анализировать и, возможно, изменять свое поведение [7].
Рефлексия состоит из самоанализа (introspection), позволяющего приложению наблюдать за собственным поведением, и самовоздействия (intercession), обеспечивающего ему возможность менять поведение на основе этих наблюдений. Скажем, в распределенном приложении программные «датчики» способны использовать самоанализ для наблюдения и генерации отчетов о шаблонах применения разных компонентов. Благодаря самовоздействию выполняющаяся программа может добавлять новые виды «датчиков» и компоненты, которые реализуют корректирующие действия.
Как показано на рис. 2, «рефлексирующая» система (объекты базового уровня) и ее самоописание (объекты метауровня) взаимосвязаны. Изменения одного из них отражаются на другом.
Протокол метаобъектов (metaobject protocol, MOP) — это интерфейс, который позволяет объектам базового уровня систематически выполнять самоанализ и самовоздействие. MOP поддерживает либо структурную, либо поведенческую рефлексию [3]. Структурная рефлексия относится к иерархии классов, взаимосвязям объектов и типам данных. Так, метаобъект способен анализировать объект базового уровня, чтобы определить, какие методы можно вызывать. Поведенческая рефлексия связана с вычислительной семантикой приложения. Например, распределенное приложение использует поведенческую рефлексию для выбора и загрузки коммуникационного протокола, который лучше всего соответствует текущему состоянию сети.
Разработчик может применять сервисы рефлексии, встроенные в язык программирования (скажем, CLOS, Python или варианты Java) либо предоставленные платформой промежуточного слоя. В сочетании с аспектно-ориентированным программированием рефлексия позволяет с помощью MOP добавлять в выполняемое приложение код для решения общих задач. Динамическая загрузка и выгрузка адаптивного кода требуют, чтобы соответствующие модули предоставляли возможность подключения в режиме plug-and-play.
Компонентный дизайн
Компоненты представляют собой программные модули, которые можно разрабатывать, устанавливать и составлять независимо друг от друга [9]. Среди популярных компонентных платформ можно назвать COM/DCOM, .Net, Enterprise Java Beans и CORBA Component Model.
При компонентном дизайне поддерживаются два типа композиции. В случае использования статической композиции разработчик может объединять несколько компонентов во время компиляции для формирования приложения. Если же применяется динамическая композиция, разработчик может добавлять, удалять или менять конфигурацию компонентов во время исполнения приложения. Для обеспечения динамической композиции инструментальная среда должна поддерживать позднее связывание, которое позволяет объединять совместимые компоненты с помощью хорошо определенных интерфейсов, так называемых контрактов. Кроме того, для обеспечения согласованности с другими приложениями среда должна поддерживать несколько версий компонентов.
Поскольку компонентное проектирование позволяет объединять готовые компоненты, созданные разными производителями, оно способствует многократному использованию программных модулей. Механизмы обслуживания компонентной структуры программы после ее первоначальной реализации в сочетании с поздним связыванием поддерживают композиционную адаптацию.
Средства промежуточного слоя и другие
Помимо возможности применения трех базовых технологий, поддерживающих динамическую рекомпозицию, развитию этого направления способствует целый ряд других факторов. Возможно, самым важным из них является растущая роль платформ промежуточного слоя в распределенных вычислениях. Программное обеспечение промежуточного слоя формирует уровень, который разработчики могут использовать для реализации адаптивного поведения. И действительно, многие подходы к композиционной адаптации реализуются разными уровнями средств промежуточного слоя.
Кроме того, при создании адаптивного программного обеспечения важную роль могут играть другие средства и подходы. Среди них — шаблоны проектирования, мобильные агенты, порождающее и адаптивное программирование, программирование намерений [5].
Классификация средств композиционной адаптации
Исследователи и разработчики предлагают широкий спектр методов для реализации композиционной адаптации. В таблице 1 указаны исследовательские проекты, коммерческие программные пакеты и спецификации, которые поддерживают определенные виды композиционной адаптации. Этот список — далеко не исчерпывающий: он включает в себя лишь проекты, которые иллюстрируют различия в классификации, разработанной нами с учетом того, как, когда и где осуществляется композиция ПО.
Как осуществляется композиция
Первый параметр классификации связан с программными механизмами, поддерживающими композиционную адаптацию. В таблице 2 приведены несколько основных методов с краткими описаниями и примерами [8].
Все методики, перечисленные в таблице, предусматривают наличие промежуточного слоя, на котором реализуются посреднические функции при взаимодействиях программных элементов. Разные категории используемых методик позволяют программным средствам промежуточного слоя менять взаимодействия между приложением и сервисами. Однако промежуточный перехват взаимодействий для приложения незаметен, в то время как интегрированный инструментарий промежуточного слоя предоставляет сервисы адаптации, явно вызываемые приложением.
Субъект, который использует такие методики для адаптации приложения, называется сборщиком. Это может быть либо человек (разработчик или администратор, взаимодействующий с исполняемой программой с помощью графического интерфейса), либо программа (интегратор аспектов, загрузчик компонентов, среда времени исполнения или метаобъект). По мере развития технологий адаптивных вычислений роль сборщиков все чаще будут играть именно программные компоненты.
Прозрачность рекомпозиции определяется тем, когда и где сборщик меняет программу. Степень прозрачности приложения или системы зависит от того, известно ли этому приложению или системе об «инфраструктуре», необходимой для рекомпозиции. Скажем, при адаптации с помощью инструментария промежуточного слоя обеспечивается прозрачность по отношению к исходным текстам приложения — если приложение не нужно менять для реализации возможностей адаптации. Разная степень прозрачности (по отношению к исходным текстам приложения, к виртуальной машине, исходным текстам программ промежуточного слоя и т.д.) определяет переносимость предлагаемого решения между платформами и то, насколько просто можно добавлять новые возможности адаптации к существующим программам [10].
Когда выполняется композиция
Мы различаем подходы в зависимости от времени увязывания возможностей адаптации с бизнес-логикой. Вообще говоря, чем позже выполняется это связывание, тем шире возможности адаптации, но тем сложнее гарантировать согласованность измененной программы.
На рис. 3 приведена классификация адаптивных приложений в зависимости от времени выполнения композиции. На вертикальной оси указываются типы приложений, которые реализуют статическую либо динамическую композицию. Методы статической композиции реализуются во время разработки, компиляции или загрузки, а методы динамической композиции сборщик может применять во время выполнения программы.
Статическая композиция. Если композиция адаптивной программы выполняется при разработке, любое адаптивное поведение жестко прописывается в программе, и его невозможно модифицировать без изменения кода. Правда, разработчик или пользователь может реализовать ограниченные возможности адаптации во время компиляции или сборки — за счет конфигурации приложения в расчете на конкретную среду. Например, аспектно-ориентированные языки программирования, такие как AspectJ, позволяют интегрировать аспекты в программу при компиляции. Аспекты могут реализовывать принципы обеспечения отказоустойчивости или защиты, рассчитанные на конкретную среду. Чтобы такие специализируемые приложения соответствовали новой среде достаточно их перекомпилировать.
Конфигурируемые приложения откладывают окончательное решение об использовании алгоритмических единиц в конкретной среде до тех пор, пока выполняемое приложение не загрузит соответствующий компонент. Например, виртуальная машина Java (JVM) загружает классы только тогда, когда Java-приложение их впервые использует. Хотя данный подход относится к типу статической композиции, приходящейся на время загрузки, он предоставляет больший динамизм, чем другие статические методы.
Другие подходы, обеспечивающие подключение возможностей адаптации во время загрузки, подразумевают динамическую модификацию самого класса в момент его загрузки. Например, чтобы предоставить возможности мониторинга и отладки, Java-среда Kava позволяет модифицировать байт-код при загрузке класса.
Динамическая композиция. Наиболее гибкие подходы к композиционной адаптации реализуются в ходе выполнения программы. Сборщик может заменять или расширять алгоритмические и структурные модули во время исполнения, не прерывая его. В соответствии с тем, может ли сборщик менять бизнес-логику приложения, выделяют два типа подходов.
Настраиваемое программное обеспечение запрещает модификацию кода программы, отвечающего за бизнес-логику. Оно поддерживает точную настройку реализации общих задач в ответ на изменения условий среды, скажем динамических условий, возникающих в мобильном окружении. Пример тому — используемая в AspectIX фрагментная объектная модель, которая позволяет во время исполнения настраивать распределенное поведение CORBA-приложения.
В свою очередь, изменяемое программное обеспечение позволяет сборщику вносить изменения даже в обязательные функции программы. Тем самым поддерживается динамическая рекомпозиция исполняемой программы в функционально другую программу. Так, на платформе OpenORB все объекты в коде программных компонентов промежуточного слоя и приложения имеют интерфейсы вычислительной рефлексии, поэтому во время исполнения «рефлексирующее» приложение может менять практически любой объект любым образом (в том числе за счет модификации его интерфейса и внутренней реализации). Это очень мощное решение, но в большинстве случаев разработчик должен ограничивать его гибкость, чтобы гарантировать целостность системы после адаптации.
Где выполняется композиция
Последний параметр, по которому сравниваются подходы, определяет, где именно сборщик вставляет в систему адаптивный код. Это может быть один из уровней промежуточного ПО или сам код приложения. Мы не обсуждаем изменения в операционной системе, но следует отметить, что сейчас ведутся активные исследования расширяемости операционной системы. Более того, адаптация в многоуровневых средах, таких как DEOS и Grace, предусматривает взаимодействие операционной системы, платформы промежуточного слоя и приложения.
Уровни средств промежуточного слоя. Проекты, предусматривающие композиционную адаптацию на уровне средств базовой инфраструктуры, подразделяются на две группы.
Один из подходов заключается в создании уровня коммуникационных сервисов, обеспечивающих адаптацию. ACE — один из первых примеров использования динамического связывания C++ для поддержки коммуникационных сервисов и сервисов обработки событий, используемых для адаптации программ. В совокупности они формируют многоуровневую среду, позволяющую распределенному приложению выбирать конкретный коммуникационный протокол.
Второй подход — предоставление виртуальной машины, способной перехватывать и перенаправлять взаимодействия. Например, JVM и среда Common Language Runtime (CLR) реализуют динамическую реорганизацию за счет служб отображения, предоставляемых, соответственно, языком Java и платформой .Net. R-Java поддерживает метаобъекты с помощью добавления новой команды к интерпретатору Java, а Prose и Iguana/J используют интеграцию аспектов для добавления поведенческого отражения к стандартной виртуальной машине Java. В целом, подходы этой категории — очень гибкие в отношении динамической реорганизации, поскольку позволяют предоставлять новый код во время исполнения программы. Однако для обеспечения прозрачности в них применяются специализированные виртуальные машины, что может ограничить переносимость приложений.
При работе с некоторыми инструментальными средами разработчик приложений создает явные обращения к сервисам адаптации. Примером реализации такого подхода могут служить Orbix, Orbix/E, ORBacus, CIAO и Boeing Bold Stroke. Для управления последовательностью вызовов в QuO используются обертки вокруг суррогатов и скелетонов CORBA, в то время как IRL и ACT задействуют для этого мобильные перехватчики (interceptor). Последние служат «обобщенными метками» перехвата, которые сборщик может применять во время выполнения приложения для загрузки других типов перехватчиков. Поскольку пользователь способен загрузить мобильный перехватчик с помощью параметра командной строки, этот подход позволяет сборщику интегрировать адаптивные компоненты в программу без изменения кода приложения и кода программ промежуточного слоя.
Код приложения. Подходы, опирающиеся на ПО промежуточного слоя, поддерживают прозрачную адаптацию, но применимы только к программам, которые пишутся для конкретной платформы. Более общий подход заключается в том, что разработчики реализуют композиционную адаптацию в самом приложении. Существуют две основные методики.
Первая — создание кода приложения или его части с помощью языка, напрямую поддерживающего динамическую рекомпозицию. Некоторые языки (например, CLOS и Python) предоставляют такую поддержку изначально, а другие соответствующим образом расширяются. Скажем, Open Java, R-Java, Handi-Wrap, PCL и Adaptive Java расширяют Java, поскольку включают в себя дополнительные ключевые слова и конструкции, повышающие выразительность адаптивного кода. Однако при создании программы разработчик должен использовать эти возможности явно.
Вторая методика — интеграция возможностей адаптации в функциональный код. AspectJ и Composition Filters интегрируют соответствующие возможности в существующие приложения во время компиляции. Инструменты, подобные TRAP/J, используют двухэтапный подход к поддержке динамической рекомпозиции. Сначала модуль интеграции аспектов добавляет обобщенные метки перехвата (в данном случае они реализуются как аспекты) в код приложения во время компиляции. Потом во время исполнения приложения сборщик динамически включает в него новые адаптивные компоненты.
Этот подход позволяет добавлять возможности адаптации к существующим приложениям прозрачно относительно исходного кода. Такое решение весьма актуально, поскольку пользователи рассчитывают, что унаследованные приложения будут работать эффективно на любых компьютерах, а они становятся все разнообразнее.
Основные трудности
Несмотря на постепенное совершенствование механизмов поддержки композиционной адаптации, потенциал динамически рекомпозируемых программных систем в значительной мере зависит от достижений в таких областях, как обеспечение корректности, безопасности, интероперабельности и принятие решений.
Гарантия корректности
Проектирование рекомпозируемых программ требует такой парадигмы программирования, которая поддерживает автоматическую проверку как функциональных, так и нефункциональных свойств системы [11].
Чтобы гарантировать корректность адаптируемой системы, разработчики должны сначала сертифицировать все компоненты, то есть подтвердить их корректность относительно спецификаций. Они могут пройти сертификацию либо за счет выбора компонентов, правильность которых уже подтверждена с помощью традиционных методов (тестирование, инспектирование, верификация на базе моделей и т.д.), либо с помощью автоматической генерации кода по спецификациям. Помимо функциональных, сертификация может включать и нефункциональные требования (например, требования к безопасности и производительности).
Кроме того, необходимы методики, гарантирующие, что адаптированная система по-прежнему работает приемлемым образом или безопасна. Для решения этой задачи принято использовать анализ зависимостей. Также разработчики могут применять высокоуровневые контракты [12] и инварианты для мониторинга корректности системы до, во время и после адаптации.
Безопасность
В то время как гарантия корректности связана преимущественно с целостностью системы, задача обеспечения безопасности — уберечь систему от вторжений, не дав злоумышленникам возможности использовать механизмы адаптации в своих целях. Адаптивная программная система должна не только проверять корректность исходных текстов компонентов, но и защищать от злоумышленников свое ядро. Существует множество хорошо изученных механизмов защиты — наподобие надежного шифрования для гарантии конфиденциальности и аутентификации сообщений, связанных с адаптацией.
Интероперабельность
Распределенные системы, способные адаптироваться к среде, должны настраивать отдельные компоненты и координировать такую настройку на различных системных уровнях и платформах. Программные компоненты, как правило, поставляются разными производителями, поэтому разработчику придется интегрировать механизмы адаптации для удовлетворения требований распределенного приложения. Проблема усложняется многообразием подходов к реализации адаптивного ПО на различных системных уровнях. А решения, относящиеся к одному и тому же уровню, зачастую несовместимы. Разработчикам необходимы инструментальные средства и методы интеграции адаптивных компонентов на разных уровнях одной системы, между несколькими системами и разными «платформами» адаптации.
Принятие решений
Адаптивные системы реагируют на меняющийся физический мир. Они должны действовать автономно, модифицируя структуру ПО в соответствии с конкретной средой, предотвращая сбои и перерывы в работе. Чтобы определить, как, когда и где выполнять адаптацию системы, модули принятия решений используют информацию, получаемую от программных и аппаратных сенсоров. Некоторые системы могут даже требовать, чтобы эти модули «изучали» поведение пользователей и адаптировались к нему.
Одни исследователи создают программные инструменты принятия решений, опираясь на подходы на базе правил или теорию управления. Другие проектируют модули принятия решений, действия которых подобны «биологическим» процессам, таким, как нервная деятельность человека или поведение колоний насекомых. Эти подходы достаточно эффективны в определенных предметных областях, но динамика среды и сложность программ ограничивают их повсеместное распространение. Необходимы всесторонние исследования в области принятия решений об адаптации ПО. Будущие системы должны получать самую разную информацию от сенсоров, продолжать обучаться с учетом нового опыта и приступать к использованию новых подходов по мере их появления.
***
Создано уже немало механизмов композиционной адаптации, и можно предположить, что они будут использоваться все шире по мере того, как программисты будут больше узнавать о методиках адаптивного ПО, а общество — готовиться к появлению самоуправляемых компьютерных систем. Композиционная адаптация — мощный механизм, но при отсутствии приемлемых инструментальных средств для автоматической генерации и проверки кода ее использование может негативно повлиять на целостность и безопасность системы.
Должны быть созданы технологии и инструменты разработки, в полной мере опирающиеся на достижения программной инженерии и способные поддерживать композиционную адаптацию. Такой фундамент позволит следующему поколению компьютерных систем обрести новый уровень гибкости, автономности и обслуживаемости без ущерба для безопасности.
Литература
- M. Weiser. Hot Topics: Ubiquitous Computing/ Computer, oct. 1993.
- J.O. Kephart, D.M. Chess. The Vision of Autonomic Computing/ Computer, jan. 2003.
- G.S. Blair et al. An Architecture for Next-Generation Middleware/ Proc. IFIP Int?l Conf. Distributed Systems Platforms and Open Distributed Processing (Middleware 98), Springer, 1998.
- D.L. Parnas. On the Criteria to Be Used in Decomposing Systems into Modules/ Comm. ACM, dec. 1972.
- K. Czarnecki, U. Eisenecker. Generative Programming, Addison-Wesley, 2000.
- G. Kiczales et al. Aspect-Oriented Programming/Proc. European Conf. Object-Oriented Programming (ECOOP), LNCS 1241, Springer-Verlag, 1997.
- P. Maes. Concepts and Experiments in Computational Reflection/ Proc. ACM Conf. Object-Oriented Programming Systems, Languages and Applications (OOPSLA), ACM Press, 1987.
- M. Aksit, Z. Choukair. Dynamic, Adaptive and Reconfigurable Systems Overview and Prospective Vision/ Proc. 23rd Int?l Conf. Distributed Computing Systems Workshops (ICDCSW03), IEEE CS Press, may 2003.
- C. Szyperski. Component Software: Beyond Object-Oriented Programming, 2nd ed., Addison-Wesley, 2002.
- P.K. McKinley et al. A Taxonomy of Compositional Adaptation/ tech. report MSU-CSE-04-17, Dept. Computer Science and Engineering, Michigan State Univ., 2004.
- N. Venkatasubramanian. Safe ?Composability? of Middleware Services/ Comm. ACM, june 2002.
- A. Beugnard et al. Making Components Contract Aware/ Computer, july 1999.
Филип Маккинли (mckinley@cse.msu.edu) — профессор факультета компьютерной науки и инженерии Мичиганского университета. Сайед Масуд Саджади (sadjadis@cse.msu.edu) — аспирант факультета компьютерной науки и инженерии Мичиганского университета. Эрик Кастен (kasten@cse.msu.edu) — программный инженер Национальной лаборатории сверхпроводимости Мичиганского университета. Бетти Ченг (chengb@cse.msu.edu) — профессор факультета компьютерной науки и инженерии Мичиганского университета.
Программное обеспечение промежуточного слоя и адаптация
Большая часть новейших исследований в области адаптивных программ посвящена ПО промежуточного слоя, то есть уровню сервисов, отделяющему приложения от операционной системы и сетевых протоколов. Дуглас Шмидт выделяет четыре категории (рис. А) программных средств промежуточного слоя (D. Schmidt. Middleware for Real-Time and Embedded Systems/ Commmunications of ACM, june 2002).
Промежуточные средства базовой инфраструктуры (host-infrastructure middleware)размещаются над операционной системой и предоставляют высокоуровневый интерфейс API, скрывающий разнородность аппаратуры, операционных систем и, до определенной степени, сетевых протоколов.
Промежуточные средства распределения (distribution middleware)предоставляют высокоуровневые программные абстракции (например, удаленные объекты), позволяя разработчикам писать распределенные приложения во многом так же, как и автономные программы. К этому уровню, в частности, относятся CORBA, DCOM и Java RMI.
Общие сервисы (common middleware) включают в себя обеспечение отказоустойчивости, безопасности и долговременности, а также транзакций с участием удаленных объектов.
Специализированные сервисы (domain-specific middleware) создаются в расчете на требования конкретных классов приложений.
Наибольшими возможностями адаптации обладает ПО промежуточного слоя, созданное на основе парадигмы объектно-ориентированного программирования и опирающееся на популярные платформы наподобие CORBA, Java RMI и DCOM/.Net. Многие из подходов к реализации адаптивного инструментария промежуточного слоя предусматривают перехват и изменение сообщений. На рис. B представлена последовательность запросов и ответов в упрощенном клиент-серверном приложении на базе CORBA. Это приложение состоит из двух автономных программ, которые размещаются на двух компьютерах, связанных сетью.
Предположим, клиент содержит корректную CORBA-ссылку на обслуживающий модуль (servant). Клиент, посылая запрос к обслуживающему модулю, сначала обращается к суррогату (stub), который представляет CORBA-объект на стороне клиента. Суррогат упаковывает запрос и посылает клиентскому брокеру (object request broker, ORB). Клиентский брокер передает запрос серверному брокеру, где скелетон (skeleton) распаковывает запрос и передает обслуживающему модулю; тот отвечает на запрос через серверный брокер и скелетон. Клиентский брокер получает ответ и направляет его клиенту.
За последние годы проведено немало исследований, посвященных возможностям адаптации ПО промежуточного слоя к динамическим гетерогенным средам для лучшего обслуживания приложений (Communications of ACM, Special issue on adaptive middleware, june 2002). Программные средства промежуточного слоя скрывают распределение ресурсов и гетерогенный характер платформы от бизнес-логики приложения. Поэтому логично реализовать именно на этом уровне возможности адаптации, необходимые для выполнения общих задач.
Philip K. McKinley, Seyed Masoud Sadjadi, Eric P. Kasten, Betty H.C. Cheng. Composing Adaptive Software. IEEE Computer, July 2004. IEEE Computer Society, 2004, All rights reserved. Reprinted with permission.