Что такое RUP — формализованное описание работ и задач, которые надо обязательно выполнить, или набор принципов, сформулированных на основе анализа реального опыта разработки программного обеспечения, использование которых позволяет найти разумное решение почти в любой практической ситуации?

Методология разработки программного обеспечения Rational Unified Process (RUP) достаточно известна в России. Однако четкого представления среди практиков относительно того, что такое RUP, кому, когда и зачем стоит ее внедрять, по-прежнему нет. К сожалению, представление о том, что RUP — это тяжелый формализованный процесс, и некоторые другие заблуждения, часто приводят к нежеланию разработчиков знакомиться с ним и использовать его достоинства в своей работе или, наоборот, к недопониманию того, что и зачем они намерены внедрять.

Три лица RUP

На вопрос «Что такое RUP» есть, по крайней мере, три корректных ответа. RUP — философия и практика успешной разработки программного обеспечения; RUP — формальное описание процесса; RUP — готовый сайт, содержащий формальное описание процесса. В статьях, посвященных RUP, часто основное внимание уделяют второму и третьему ответам. Действительно, RUP — это хорошо структурированное описание процесса разработки программного обеспечения, содержащее перечень работ и задач, выполняемых в ходе разработки, а также создаваемых при этом документов и моделей. Одновременно RUP — это Web-сайт, содержащий описание данного процесса с возможностями настройки персонального представления готового сайта. Часто RUP описывают как процесс, предполагающий выполнение таких-то и таких-то работ и задач в таком-то порядке, создание таких-то и таких-то артефактов (создаваемые в ходе разработки модели, документы, коды программ и т.п.). Или — что близко — описывают содержание Web-сайта RUP, распространяемого как готовый продукт.

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

Терминология и подход RUP

Статическую структуру RUP составляют описания работ и задач (части работы), описания создаваемых артефактов, а также рекомендации по их выполнению, которые группируются в дисциплины: шесть основных — бизнес-моделирование (Business Modeling), управление требованиями (Requirements), анализ и проектирование (Analysis and Design), реализация (Implementation), тестирование (Test), внедрение (Deployment), и три вспомогательных — управление конфигурациями и изменениями (Configuration and Change Management), управление проектом (Project Management), поддержка среды разработки (Environment).

Динамическую структуру процесса составляют фазы и итерации. Проект, как правило, делится на четыре фазы: начало (Inception), проработка (Elaboration), построение (Construction) и передача (Transition). Фазы, в свою очередь, делятся ни итерации. В ходе каждой итерации выполняются работы и задачи из различных дисциплин; соотношение этих работ меняется в зависимости от фазы.

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

Создатели RUP определяют его как итеративный, архитектурно-ориентированный и управляемый прецедентами использования процесс разработки программного обеспечения [1]. Согласно последней доступной автору версии RUP (Version 2003.06.00.65) к этому надо добавить, что RUP использует лучшие практические методы (итеративная разработка, управление требованиями, использование компонентной архитектуры, визуальное моделирование, непрерывный контроль качества, управление изменениями) и десять элементов, представляющих квинтэссенцию RUP (разработка концепции; управление по плану; снижение рисков и отслеживание их последствий; тщательная проверка экономического обоснования; использование компонентной архитектуры; прототипирование, инкрементное создание и тестирование продукта; регулярные оценки результатов; управление изменениями; создание продукта, пригодного к употреблению; адаптация RUP под нужды своего проекта).

Пользоваться таким объемным определением, конечно, неудобно. Поэтому для характеристики RUP Пером Кроллом введено понятие «Дух RUP» [2]. Хотя оно не входит в «канонический» текст RUP, но предложено человеком, который, являясь директором соответствующего направления в компании IBM, связан с RUP самым непосредственным образом. Дух RUP заключен в восьми принципах:

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

Эти принципы весьма полно характеризуют RUP и в наибольшей степени соответствуют современному стилю разработки программного обеспечения.

Некоторое время тому назад автору довелось участвовать в проекте, который был выполнен в соответствии с принципами RUP. Речь идет о разработке системы управления гостиницей, предназначенной для работы в режиме аренды приложения (application service providing, ASP) [3]. Создаваемая система обладала трехзвенной архитектурой с тонким клиентом, что позволяло избежать процедуры инсталляции системы в гостинице (система развертывалась в удаленном центре, в котором были установлены серверы, а пользователи из гостиницы просто получали адрес для доступа к системе) и последующего администрирования системы «у клиента».

В начале проекта для его выполнения проекта была создана команда из четырех человек. В пиковые периоды их численность вырастала до полутора десятков (не считая привлекаемых консультантов). Готовых специалистов со знанием особенностей трехзвенной архитектуры в составе команды не было. Этих двух моментов уже достаточно, чтобы оценить проект как весьма рискованный.

Работа над проектом началась с небольшой итерации, в ходе которой были определены границы системы (попросту говоря, перечислены примеры ее использования) и проверена принципиальная реализуемость системы на двух ключевых примерах — «бронирование номера» и «формирование отчета о занятых номерах». Был собран макет, включающий сервер баз данных, сервер приложений и несколько HTML-страниц.

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

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

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

Скажем, пример «оплата проживания» реализовывался в трех последовательных итерациях. В первой из них была реализована базовая функциональность — оплата наличными всей начисленной суммы. А в последующих итерациях реализовались сценарии частичной оплаты, а также использования банковских карточек и чеков.

Итеративность

RUP относится к итеративным методологиям. Обычно говорят, что в соответствии с RUP процесс разработки разбивается на четыре фазы, а фазы, в свою очередь, делятся на итерации. Но лучше сформулировать это немного иначе: разработка разбивается на итерации, а однотипные итерации группируются в фазы [4].

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

Разбивание проекта на итерации проводится с использованием принципов, входящих в состав Духа RUP. Это атака на риски, активное приспособление к изменениям, раннее создание архитектурного каркаса, разработка системы из компонентов.

Ориентация на архитектуру

Принципиальное отличие RUP от многих других итеративных подходов состоит в большом внимании к разработке архитектуры системы. Надо пояснить, что в RUP называется архитектурой. Даже знакомые с RUP специалисты иногда считают, что архитектура — это наиболее общее описание системы [5], и ее разработка сводится практически к выбору между тонким и толстым клиентом. В RUP понятие архитектуры не ограничивается этими принципиальными решениями, а включает, в частности, используемые в проекте типовые решения для доступа к СУБД, реализации параллельных процессов и т.д. Но и это не все. Архитектура в RUP — это еще и ключевая часть кода (обычно, до 20% общего объема), которая позволяет продемонстрировать соответствие системы основным функциональным и нефункциональным требованиям. Поэтому в RUP часто говорится об исполняемой архитектуре (executable architecture). Чтобы избежать этого не совсем привычного для русского языка сочетания, в дальнейшем будем использовать выражение «архитектурный каркас».

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

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

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

Поскольку на начальной стадии проекта у нас не было традиционного заказчика (будущего пользователя), то простота общения с заказчиком нас не волновала. Но и в этом случае мы получили реальную пользу от использования примеров использования в качестве единицы измерения работы над проектом. Раздача заданий «по примерам» и, особенно, контроль выполнения проекта по завершенным примерам позволили четко держать «руку на пульсе». Во всяком случае, традиционного состояния «выполнено 90%, осталось 90%» удавалось избегать. Также использование примеров использования существенно облегчило организацию тестирования и разработку документации пользователя. Тестировщики, как правило, без труда готовили тесты по описаниям примеров использования, реализуемых в очередной итерации. А технический писатель готовил черновой вариант пользовательской документации. При этом и то, и другое делалось до завершения разработки соответствующих примеров.

Процесс, управляемый примерами

Из каких единиц функциональности состоит проект? Можно ли сказать, что любое, самое незначительное добавление функциональности повышает пользовательскую ценность системы? Как правило, существуют определенные наборы функциональности, которые либо должны поддерживаться системой целиком, либо их вообще не имеет смысла автоматизировать. Именно такой набор функциональности, позволяющий пользователю решить содержательную и действительно нужную ему задачу, и называется в UML примером использования. Соответственно, разработка программного обеспечения в RUP ориентируется именно на такие «кванты». Либо вы полностью реализуете пример использования в вашей системе, и пользователь получает реальную автоматизацию своих бизнес-процессов, либо нет. В последнем случае не важно, на сколько процентов вы реализовали пример использования: пользоваться им все равно нельзя. Скажем, либо вы реализуете возможность выписать счет для покупателя, либо нет — и тогда не важно, какие функции упорядочивания и фильтрации списков товаров вы уже реализовали.

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

Нельзя не отметить, что ориентация на примеры использования — это способ описать функциональность системы в форме и терминах, максимально понятных заказчику. В результате заказчик оказывается в большей мере привлечен к процессу разработки, чем при описании функциональности в терминах проектировщика, как это принято в стандартном ТЗ по ГОСТ 19 или 34.

Дух RUP

Дух RUP — это те ключевые принципы, которые некий итеративный процесс и превращает в RUP.

Атаковать риски как можно раньше

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

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

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

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

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

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

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

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

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

Разрабатывать именно то, что нужно заказчику

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

Главное внимание — исполняемой программе

Главный результат, которого ждет от вас заказчик, — работающая система. Никакие документы и модели сами по себе не важны. Они важны лишь настолько, насколько помогают создать и поддерживать работающую систему. Еще на один аспект этой проблемы обращает внимание Эдвард Йордон: срок жизни программ в наши дни часто не превышает пары лет [6]. Затем они нередко заменяются совершенно другими программами, часто выполненными в другой технологии и реализующими другие бизнес-правила. Всегда ли нужна ли в такой ситуации детальная тщательно проработанная проектная документация? Или ее разработка приведет только к неоправданному завышению стоимости разработки? Конечно, вопрос этот в каждом конкретном случае требует серьезного анализа. Но важно понять, что простой рецепт «документации всегда должно быть много» не является безоговорочно верным.

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

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

Вместе с тем, в этот период удалось существенно «подчистить» имеющиеся огрехи и, в частности, существенно сократить время отклика системы, например, при формировании статистических сводок. Рефакторинг кода не относится к традиционным приемам RUP, однако его применение в ограниченном объеме оказывает очень успешное влияние на повышение качества технических решений. Обычно подобный рефакторинг проводился в форме «субботника», когда объявлялось заранее, что предстоит изменить структуру пакетов PL/SQL или переработать такие-то функции на Java Script с такими-то и такими-то целями. И объявлялся день Х, посвященный этим работам. В результате, удавалось настроить участников проекта на выполнение неинтересной работы по внесению изменений в работающий код.

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

Приспосабливаться к изменениям с самого начала проекта

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

Создавать архитектурный каркас как можно раньше

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

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

Итак, первый работающий прототип системы, послуживший основой архитектурного каркаса, был выполнен еще до завершения сбора пожеланий заинтересованных лиц (в нашем случае — консультантов проекта). Это позволило своевременно отказаться от некоторых оказавшихся неудачными решений, например, от излишне сложного для Web-приложения интерфейса. С другой стороны, на первых прототипах были отработаны принципиальные решения для доступа к СУБД, для построения HTML-таблиц с расширенной функциональностью (выделение одной или нескольких строк, редактирование с контролем правильности введенных значений и т.п.), для поддержки многоязычного интерфейса с мгновенным переключением с языка на язык.

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

Разрабатывать систему из компонентов

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

Компоненты не нужно путать с использованием объектных языков. Компонентом может быть и библиотека процедур, написанных на не объектном языке, и даже группа таблиц баз данных Oracle вместе с пакетом хранимых процедур на PL/SQL для работы с ними. Важно то, что доступ к компоненту осуществляется только через хорошо определенный интерфейс.

Еще одно достоинство компонента состоит в том, что его можно использовать повторно или заменить другим компонентом; достаточно проверить, что сохранен старый интерфейс.

Работать как одна команда

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

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

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

Компоненты можно использовать повторно для решения аналогичных задач в другом проекте. В нашем проекте таким компонентом стал модуль поддержки использования IP-телефонов (телефонный аппарат с небольшим дисплеем и возможностью работы в режиме браузера) для доступа к системе. IP-телефон позволял клиентам гостиницы получать различную справочную информацию или заказывать услуги, а сотрудникам гостиницы — передавать в систему сведения о выполненных заданиях, например, о завершении уборки номера. Четко определенные интерфейсы позволили сделать модуль легко настраиваемым для работы с различными системами управления гостиницами.

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

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

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

Качество — стиль жизни

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

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

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

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

Дух или буква?

RUP включает в себя тщательно расписанный подход к разработке — перечень работ и задач, которые нужно выполнять; Список артефактов, которые нужно разрабатывать в соответствие с приведенными шаблонами. Но, с другой стороны, RUP — это довольно общие подходы, дух и лучшие практические методы. Следование этим методам вовсе не предполагает выполнения всех перечисленных в RUP работ или формирования всех перечисленных артефактов. А уж тем более, следования всем шаблонам и рекомендациям. Что же здесь первично? Что именно позволяет утверждать, что одна команда работает в соответствии с RUP, а другая — нет?

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

В ходе проекта мы вовсе не пытались выполнить все прописанные в RUP работы и задачи. Тем более — разработать и оформить все предлагаемые RUP артефакты. Но следование (пусть и не всегда осознанное) духу RUP позволило справиться со многими проблемами, а других просто избежать.

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

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

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

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

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

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

Литература
  1. А. Якобсон, Г. Буч, Дж. Рембо, Унифицированный процесс разработки программного обеспечения. СПб.: Питер, 2002.
  2. Kroll, The Spirit of the RUP. www-106.ibm.com/developerworks/rational/library/ content/RationalEdge/dec01/ TheSpiritoftheRUPDec01.pdf
  3. Алексей Закис, Михаил Лужецкий, Николай Приезжий, "Персональная среда разработки интернет-приложений". Oracle Magazine RE, Август/сентябрь 2002.
  4. Philippe Kruchten, Going Over the Waterfall with the RUP. www-106.ibm.com/developerworks/rational/library/ 4626.html
  5. Константин Берлинский, Как добиться успеха в безнадежных проектах. Открытые системы, 2002, № 10.
  6. Эдвард Йордон, Управление сложными интернет-проектами. М.: "Лори", 2003.

Алексей Закис (azakis@mail.ru) — главный специалист ИК «Сибинтек» (Москва).