Способность древних римлян строить города была одним из признаков их технологического прогресса. После того, как власти определяли удобное со стратегической точки зрения место, градостроители проектировали город. Для того чтобы разработать эффективный план, архитектор сначала оценивал имеющиеся ресурсы — вода, строительные материалы, земли, подходящие для занятия сельским хозяйством, дороги. Эти ресурсы определяли потенциальную численность жителей нового города. Затем строители возводили стены, определяя границы проживания максимального количества жителей, и устанавливая точки, с которых горожане могли бы эффективно оборонять город. Строители сооружали главные здания, создавая необходимую инфраструктуру на основе плана, предложенного архитекторами.
Если город процветал, то все больше людей приезжало туда и селилось в нем. Несмотря на то, что стены сдерживали рост населения, со временем жители начинали строить дома и устраивать фермы за пределами городских стен, невзирая на риск подвергнуться нападению врагов. Городские власти импортировали товары, чтобы компенсировать нехватку местных ресурсов. Однако из-за незащищенности путей подвоза этих товаров город оставался уязвимым перед внешним врагом. Как ни странно это звучит, но именно процветание города могло, в конце концов, стать одной из причин его гибели.
Наиболее удачные программные системы часто повторяют судьбу процветавших античных городов. Разработчики проектируют программные системы с учетом потребностей и ограничений, накладываемых внешними факторами, которые со временем меняются. Эти системы могут прекрасно соответствовать имеющимся на данный момент целям, рынку или направлению бизнеса и быть популярными у пользователей. Но по мере роста числа пользователей системы, растет и спрос на нее. Этот спрос может негативно повлиять на производительность системы, если будет превышен предполагаемый ее создателями объем ресурсов. Спрос может инициировать появление возможностей, не поддерживаемых в исходной архитектуре программной системы. В таких случаях возникает необходимость изменить программное обеспечение. В конце концов, разработчики решают удовлетворить эти требования, опираясь на несовместимые ограничения по ресурсам. Как и строительство зданий за пределами городских стен, это рискованное решение, способное поставить систему под угрозу. С каждым следующим разом менять программное обеспечение становится все сложнее, и система теряет стабильность. Как ни парадоксально, именно успех программной системы способен привести к ее краху.
Разработчики программного обеспечения сталкиваются с ситуацией, аналогичной той, в которой оказывались их предки, строившие города, но теперь есть специалисты, способные помочь в создании и развитии систем, быстро и эффективно реагирующих на меняющуюся среду.
Управление сложностью и изменениями
Под сложностью программного обеспечения понимают то, насколько трудно его анализировать, разбираться в нем или объяснять его работу. На рис. 1 показана тенденция, которая сохраняется с середины 70-х годов. Общество все больше зависит от программного обеспечения, а размер и сложность программных систем растут, в силу чего в таких системах все труднее разбираться и их развивать. С появлением технологий Web-сервисов, систем на базе агентов, самоуправляемых и самовосстанавливающихся систем, реконфигурируемых вычислений и других новшеств эта тенденция значительно усилилась. Сложность программного обеспечения увеличивается и за счет объема (структурная сложность), и за счет взаимодействий (социальная сложность). Кроме того, большинство технологий, которые мы используем для разработки, поддержки и развития программных систем, неадекватно решают проблемы, связанные со сложностью и изменениями.
Традиционно сложилось так, что программисты пытаются упростить системы путем их декомпозиции на управляемые компоненты для того, чтобы сохранять число элементов и их структуру в разумных пределах, однако Internet и реализация программного обеспечения в виде сервисов привели к появлению нового вида сложности. То, что Хосе Луис Фидейро называет социальной сложностью программного обеспечения, возникает из-за запутанности и увеличения числа системных взаимодействий (см. Designing for Software’s Social Complexity, Computer, Jan. 2007). Сервисы по природе своей социальны, и взаимодействия зависят от самых разных взаимосвязей и параметров, таким образом, надежность сервисных архитектур в большей степени зависит от гибкости и возможности самокомпоновки, чем от размера системы и ее структуры.
Web-сервисы
Рассмотрим транснациональную компанию, каждый месяц готовящую материалы (изначально на английском языке), которые необходимо перевести на другие языки для рассылки клиентам по всему миру. Компания пользуется услугами брокера Web-сервисов для того, чтобы приобрести и объединить все сервисы, необходимые для перевода материалов и рассылки электронных копий по офисам в каждой из стран, где работает компания. Предположим, что существуют конкурирующие провайдеры сервисов перевода и что можно получить приемлемые по качеству переводы. Поставщик передает заказ на работу брокеру сервисов, а тот, в свою очередь, определяет подходящего провайдера с учетом требований клиента и стоимости сервиса. Клиент соглашается на предлагаемые условия, а провайдер переводит и рассылает материалы.
Если бы разработчики могли создать компоненты программного сервиса для данной конкретной ситуации, программные инструментальные средства анализа влияний и визуализации могли бы без труда предоставить традиционные описания структуры и зависимостей, необходимые для того, чтобы ориентироваться в системе. Однако здесь будут отсутствовать важные аспекты бизнес-взаимодействия, необходимые для разрешения потенциально возможных проблем.
Предположим, перевод на французский язык содержал ошибки, и их необходимо исправить. Кто будет решать проблему? Не клиент, поскольку после первого использования сервиса с ним он работать больше не может. Не специалист по поддержке, поскольку код и даже исполняемый образ локально исправить невозможно. В этой ситуации брокер может, конечно, вести переговоры о решении проблемы, но будет ли это сделано вовремя? Поскольку процесс неадекватно собирает информацию о различных взаимодействиях и их сложностях, возникают проблемы, связанные с ответственностью. Попытка понять, каковы зависимости и взаимосвязи между предоставляемыми сервисами и провайдерами, превращается в непосильную задачу: брокер зачастую нечетко представляет себе границы знаний и обнаружить проблему с помощью обычного анализа влияний порой невозможно. Этот пример показывает, что существующая практика применения метода анализа влияний в программном обеспечении не подходит для решения проблем, проистекающих из вновь возникшей потребности.
Самоуправляемые и самовосстанавливающиеся системы
Аналогичные примеры можно привести и в отношении самоуправляемых и самовосстанавливающихся систем. Представление о количестве и сложности их взаимодействий позволяет понять, какова будет реакция в изменяющейся среде. Что касается самоуправляемых систем, то Майкл Хинчи и его коллеги предположили, что микро- и макровзаимодействия со средой, а также между ее компонентами — это главное для работы мультиагентных технологий (Swarms and Swarm Intelligence, Computer, Apr. 2007). В самовосстанавливающихся системах обнаружение аномалий, диагностика, планирование замены и выбор времени исполнения зависят от взаимодействий компонентов в операционной среде, как это проиллюстрировал Дэвид Гарлан (Rainbow: Architecture-Based Self-Adaptation with Reusable Infrastructure, Computer, Oct. 2004). С появлением этих новых технологий программистам приходится снова и снова находить решения в условиях постоянно растущего числа взаимодействий и зависимостей.
Поддержка устойчивости к изменениям
В 90-х годах отрасль программного обеспечения перешла от парадигмы специализированных решений к массовой настройке в пакетных приложениях, а сегодня переходит к сервисной парадигме. Однако это не означает, что исчезнут специализированные решения или возможности массовой настройки. Учитывая, что вычислительное аппаратное обеспечение стало товаром массового потребления, а Internet делает доставку сервисов тривиальной, экономически целесообразно теперь использовать модульные компоненты, собранные в развивающиеся решения, — сервисы, которые созданы на основе канонических компонентов, получаемых из конкурирующих источников. Экономически приемлемые программные компоненты можно стандартизовать и использовать в самых разных масштабах.
Ключевой аспект программного обеспечения — это его терпимость, или устойчивость, к изменениям. С учетом перспективы обеспечения отказоустойчивости, это свойство означает способность программного обеспечения развиваться внутри границ своей первоначальной архитектуры.
Сохраняемое представление о корректном, адаптивном и совершенном изменении — традиционный аспект программного обеспечения. Однако он не согласуется с вариантной или инвариантной природой программного модуля, заложенной в принципе Мейера — «открыт для расширения, закрыт для модификации» (Object-Oriented Software Construction, Prentice Hall, 1988).
Для поддержки изменений программного обеспечения используют разные подходы, например, методы на базе моделей, действующие по принципу «сверху вниз», такие как ориентированная на модели архитектура (model-driven architecture), предложенная Object Management Group, и оперативные методы, действующие по принципу «снизу вверх», например, экстремальное программирование. Оба этих подхода призваны с разных позиций решать проблемы, которые могут возникнуть при создании программного обеспечения большого объема в сжатые сроки.
Путем серии усовершенствований и улучшений подходы на базе моделей постепенно переходят от абстрактных вычислительно независимых от платформ моделей на модели, ориентированные на конкретные платформы, организуя знания и поддерживая повторное использование на соответствующих уровнях. Сложности связаны с взаимодействиями, соответствиями и преобразованиями в развиваемых репозиториях моделей. С другой стороны, оперативные подходы, предусматривающие частый выпуск хорошо организованных версий, применяют апробированные методики, такие как разработка с использованием тестов, рефакторинг и парное программирование, направленные на снижение рисков и поддержку изменения программного обеспечения посредством контролируемых постепенных улучшений и эффективного использования коллективной работы.
Анализ и визуализация программных влияний
Сложность современных программных систем часто превышает человеческое понимание. Автоматизированная поддержка анализа и визуализации влияний изменений в программном обеспечении, а также управление программными артефактами теперь не роскошь, а необходимость. Понимание того, какое влияние изменения окажут на программное обеспечение, упрощает его проектирование, реализацию и изменение. Компромиссы становятся яснее, возможные эффекты — определеннее, а оценки — точнее.
Анализ влияния изменений в программном обеспечении (Software-Change Impact Analysis, SCIA) в основном связан с поддержкой программных систем. Изменения в программы начинают вносить с первого дня их разработки и чем больше создаваемых артефактов, тем сложнее становятся проблемы, и тем в большей степени инженерам необходимы инструменты для того, чтобы видеть и понимать, что они делают.
SCIA развивается из анализа, ориентированного на исходные тексты, зарекомендовавшего себя в проектах решения «проблемы 2000 года» и перехода на евро десять лет назад. Сегодня он продолжает включать в себя все больше программных артефактов и семантически богатых представлений. Применение технологий извлечения и поиска информации открывает новые возможности определения влияний и их анализа с помощью отслеживаемых связей. Использование истории изменений для того, чтобы показать связанные по времени, сделанные ранее модификации, позволяет представить, какими должны быть стратегии создания будущих потенциально устойчивых к изменениям архитектур.
Возможно, самое значительное достижение в области SCIA — это использование технологий визуализации программного обеспечения для выявления шаблонов в программных артефактах. Визуализация значительно упрощает восприятие программного обеспечения и тем самым помогает инженерам эффективнее анализировать, понимать и объяснять аспекты программных систем. n
Шон Бонер (sbohner@vt.edu) — доцент факультета информатики технического университета Вирджинии.
Shawn Bohner. An Era of Change-Tolerant Systems. IEEE Computer, June 2007. IEEE Computer Society, 2007. All rights reserved. Reprinted with permission.