Анализ и оценка методов разработки программного обеспечения (Agile)

Враг: предваряющий анализ

Показывать лекцию целиком

3.1 Прогнозируемость не значит "водопад"

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

Хотя прогнозируемый процесс или водопад приводят к трудностям, многие люди и организации пытаются заставить водопад работать [Schwaber 2012, стр. 29].

Позже в том же абзаце:

[Пользователь использовал] службы от фирмы PriceWaterhouseCoopers (PWC). PWC подход был предсказуемым – водопадом.

В индексном указателе книги для термина "прогнозируемый процесс" сказано: "смотри Водопад".

Игра здесь в том, чтобы с термином "прогнозируемый процесс" связать отрицательные ассоциации. Этот нечестный прием уже упоминался ранее. Под "водопадом" понимается специфическая модель жизненного цикла, главная цель введения которой была скорее педагогической, поскольку она едва ли существует в практике программной инженерии. Она использовалась как учебный пример подхода, который не следует применять при разработке программных проектов. Даже в статье 1970 года [Royce 1970], в которой впервые явным образом была описана эта модель, целью была критика такого подхода. С тех пор любимое занятие ряда авторов – пинать ногами поверженную модель "водопада".

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

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

3.2 Инженерия и требования

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

3.2.1 Приемы инженерии требований

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

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

    Традиционно документ требований представляет единый последовательный текст, но этот термин покрывает и современные более гибкие форматы, такие как веб-сайт, Вики (пропагандируемые в контексте agile Ларманом [Larman 2010]) или совместно разрабатываемый документ, размещаемый в облаке, например Google Docs.

    3.2.2 Agile критика предваряющего анализа требований

    Школа agile отрицает идею требований, создаваемых на этапе проектирования. Это отрицание является общим для всех вариаций agile. Бек [Beck 2005], выступающий в поддержку XP, пишет:

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

    Кон [Kohn 2009] в контексте Scrum и как часть отрицания предваряющего анализа пишет:

    Проекты Scrum не имеют предваряющего анализа или фазы проектирования – вся работа выполняется внутри повторяющегося цикла спринтов.

    С позиций agile, создание документа требований – "лишние траты" по двум причинам.

  • Затратность: документ требований бесполезен при поставке продукта, поскольку он не является частью того, что передается клиентам. Поппендик [Poppendick lean 2002, 2004] пишет:

    Если ваша компания создает огромный документ с требованиями (эквивалент инвентарной описи), то вы в плену парадигм массовой продукции. Думайте "экономично" (lean) и вы найдете лучший путь.

    Не удивляйтесь, быть в плену парадигм – это не комплимент. Далее:

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

    Аналогия здесь с инвентаризацией, выполняемой на предприятиях и являющейся формой непроизводительных затрат.
  • Изменчивость: с позиций agile клиенты сами не знают, чего хотят. Если делать то, что они думают, то придем к нереалистичной системе. В любом случае их взгляды меняются. Единственный способ удовлетворить их – начать с построения прототипа, показать его клиентам, получить обратную связь и итеративно двигаться дальше.
  • Эти два довода – затратность и изменчивость – часто объединяются в один. Бек [Beck 2005], например, пишет:

    Разработка ПО полна непроизводительных затрат подобно созданию документов требований, которые быстро становятся устаревшими.

    И снова здесь случай критики по ассоциации: объединение двух аргументов упрощает критику требований, предваряющих создание кода. Заметьте, Бек в предыдущей цитате отвергал понятие "фазы, производящей статический документ". Но речь идет о двух различных вещах: как мы увидим далее в деталях, требования могут быть отдельной фазой процесса разработки, но их итогом является документ, который может меняться в процессе разработки.

    В действительности затратность и изменчивость – два разных аспекта, так что рассмотрим их по очереди.

    3.2.3 Критика затратности

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

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

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

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

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

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

    Таким образом, есть золотая середина между экстремальной абсурдной бюрократичностью и не менее абсурдной неформальностью.

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

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

    3.2.4 Критика изменчивости

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

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

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

    Военные стратеги любят цитировать маршала Хельмута фон Мольтке: "Ни один план сражения не выживает при встрече с врагом". Они цитируют это, продолжая строить планы! Ситуация такая же, как и в ПО. Мы знаем, что планы – всего лишь планы, и они должны адаптироваться к реалиям. Но это не причина отказа от плана.

    Обратим еще раз внимание на логическую ошибку в комментарии Бека:

    "Сбор требований не является фазой, создающей статический документ".

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

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

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

    3.2.5 Предметная область и создаваемая машина

    Сравнивая традиционный подход к выработке требований с agile подходом, полезно обратить внимание на различия между требованиями предметной области и требованиями к создаваемой машине, сформулированные много лет назад Памелой Заве и Майклом Джексоном [Zave 1997], [Jackson 1995], [Jackson 2000]. Идея проста:

  • некоторые элементы требований описывают свойства модели части мира – предметную область, в которой должна работать система;
  • другие – описывают желаемые свойства самой системы или "машины", которую хотим реализовать в проекте.
  • В банковских приложениях правила работы со счетами, депозитами, кредитами задают свойства области. Спецификации, задающие способ оплаты, другие операции – это свойства машины. При работе в области мобильной связи законы физики, определяющие скорость распространения сигнала, видимость, как и ценовая политика компании, являются свойствами области. Функции системы, которые должны учитывать эти ограничения, являются свойствами системы – машины. Согласно Джексону и Заве, следует разделять эти требования, поскольку они имеют различную природу. Проект может менять свойства "машины", но не может менять "область". Их смешивание приводит к недоразумениям и ошибкам.

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

    Что касается этих вещей, называемых "требованиями"? Реально, это кандидаты на принятие решений. Отделять требования от реализации – это просто форма передачи полномочий.

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

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

  • В бизнес системе: "Любой платеж на сумму свыше 10 000 $ должен получить одобрение управляющего". Это правило, которое следует учитывать при построении системы, никак не пытаясь его изменить. Если оно не учтено, то система будет некорректной. Что мешает компетентному менеджеру сформулировать это и подобные правила на начальном этапе? Ничто.
  • Во встроенной системе: "Все коммуникации мобильных систем телефонии должны быть согласованы с заданной частотной областью (определенной в требованиях)". Это еще один пример фундаментального ограничения, накладываемого окружением на программный проект.
  • На проекте лежит ответственность за идентификацию таких свойств области, как требования, отделяемые от решений, принимаемых при проектировании. Все это следует делать как можно раньше. Пропуск важных ограничений означает, что к тому моменту, когда они, наконец, будут обнаружены, может быть создан код, их не учитывающий и, возможно, по этой причине подлежащий существенным исправлениям. Здесь речь идет не о непрерывно возрастающей разработке, а о простой профессиональной компетентности.

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

    Скорость света не подлежит изменениям, принимаемым в результате решения на этапе реализации.

    3.3 Архитектура и проектирование

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

  • выбор абстракций (в объектно-ориентированной разработке это, в частности, абстракции данных, выражаемые как классы);
  • образцы проектирования (паттерны) – стандартные программные структуры, применимые к специфическим задачам, например, паттерн "Visitor" (Посетитель) поддерживает обход структур данных;
  • спецификации интерфейса (взаимодействия) между модулями;
  • определение структуры наследования, позволяющей организовать множество связанных абстракций в подходящую таксономию.
  • Существует некоторое различие в понятиях "проектирование" и "архитектура". Для ясности в данном контексте будем использовать термин "проектирование" для обозначения процесса, а "архитектура" – для результата процесса. Такое же соглашение будет действовать для терминов "реализация" и "код".

    3.3.1 Отделено ли проектирование от реализации?

    Многие традиционные методы программной инженерии представляют проектирование как отдельный независимый этап. Тем не менее, растет понимание того, что не существует четкой границы между проектированием и реализацией. Еще в 1968 году конференция, где программная инженерия зарождалась как научная дисциплина, включала сессию, посвященную разнице между проектированием и производством (как тогда называли реализацию). В своем выступлении Питер Наур [NATO 1968] сказал:

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

    Ему вторит Эдсгер Дейкстра:

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

    В статье Джека Ривса [Reeves 1992–2005], написанной еще в 1992 году и часто цитируемой сторонниками agile, утверждается об ошибочности говорить о том, что проектирование в программной инженерии представляет независимую деятельность. Аргументы Ривса таковы: в традиционной инженерии под проектированием понимается деятельность по созданию документации, которая затем используется в производственном процессе. В программной инженерии "производственный процесс" соответствует сборке системы (компиляции и связыванию модулей системы) и выполняется главным образом не людьми, а специальным инструментарием (компиляторами, загрузчиками, утилитой "make" и другими подобными средствами). Но затем он пишет:

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

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

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

    across subscribers as sub loop
    	sub.item.update (arguments)
    end

    Этот код применяет операцию update с заданными аргументами arguments к полю item каждого элемента sub из списка подписчиков subscribers. Я дал вам код. Если я теперь упомяну, что использовал образец проектирования – паттерн "Observer" (Наблюдатель) [Gamma 1994, Meyer 2009], то я говорю вам об архитектуре, концепции, стоящей за спиной кода. В этом классическом архитектурном решении программный элемент при всяком изменении (например, изменился курс акций) посылает сигнал, приходящий ко всем программным элементам, включенным в список подписчиков, каждый из которых выполняет свои действия по обновлению. Например, элемент интерфейса покажет новый курс, другой элемент обновит данные в базе данных. Каждый из подписчиков выполняет свою операцию обновления – update.

    Ясно, что код – это все, что мы имеем в конечном счете. Выполняется код, а не архитектурные элементы (такие, как паттерны проектирования). Но, чтобы построить этот код, понять его, когда он уже существует, критически важными являются знание и понимание элементов проектирования. Как только кто-то скажет: "Давайте используем здесь паттерн Observer", компетентный программист может произвести соответствующий код. Если код уже существует, то знание того, что это не просто произвольный код, а код, представляющий реализацию Observer, критически важно для дальнейшей успешной работы.

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

    Еще одна интересная характеристика программирования в том, что здесь, в отличие от других областей инженерии, может иметь смысл выполнять проектирование – производить документацию – после написания кода или частично до написания, частично после написания. Это хорошо объяснено в классической статье по программной инженерии: Парнас и Клементс "Рациональный процесс проектирования: Как и почему он имитируется" [Parnas 1980]. Заголовок отражает основную идею. Что привело к тому, что проект закончился созданием кода с хорошей архитектурой? Значительно реже мы спрашиваем, как была получена хорошая архитектура и, в особенности, когда – перед реализацией, как принято в жесткой модели "водопада", во время реализации, когда проектирование и реализация пересекаются, или после – для улучшения убогого документа. Возможно, применяется комбинация всех трех подходов. И это то, что, по мнению Парнаса, означает имитацию, подделку процесса проектирования [Parnas 1986]. Нечто подобное встречается в математике. Математическая статья представляет отполированный текст, описывающий последовательный путь вывода, где каждое утверждение следует из предыдущего и влечет справедливость следующего утверждения. Но если спросить математика, как он получил конечный результат, то он опишет (как это сделал Адамар в классической книге [Hadamard 1945]) намного более беспорядочный процесс, где интуиция играет такую же большую роль, как и строгость. Цель оправдывает средства.

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

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

    3.3.2 Agile методы и проектирование

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

  • если специфическая деятельность по проектированию необходима, то она должна применяться на уровне индивидуальной итерации системы, чередуясь с фазой реализации (вместо того чтобы выполнять проектирование на уровне всей системы);
  • сосредоточиваться на решении непосредственно возникших проблем (вместо того чтобы пытаться сделать расширяемое, повторно используемое решение);
  • получить хорошую архитектуру, построить на ее основе работающий код, критически проэкзаменовать архитектуру, при необходимости улучшить ее – задача, известная как рефакторинг (вместо того чтобы пытаться получить совершенное решение с самого начала).
  • Позже мы еще вернемся к обсуждению пунктов 2 и 3. Общее наблюдение состоит в том, что agile игнорирует тенденции расширяемости и повторного использования. Подобно уже ранее отмечавшимся предписаниям и здесь все начинается с корректных наблюдений, но в выводах заходят слишком далеко. Рефакторинг представляет важную технику программной инженерии, но не является заменой предваряющего проектирования. Если архитектура приличная, рефакторинг позволяет улучшить ее, но если она никуда не годна, то такой и останется.

    Активным защитником идеи проектирования на уровне индивидуальной итерации является Ларман [Larman 2010]. Вот некоторые его высказывания по поводу того, когда следует заниматься проектированием:

    "В начале построения каждого нового элемента";

    "В тот самый момент, и ни в какой другой, когда команда сочтет полезным моделировать заказ, представленный на стене".

    Стена в его описании – безграничное пространство, сплошь покрытое пользовательскими историями и другими материалами.

    С замечательной откровенностью agile тексты описывают ограничения agile подхода к проектированию. Большая часть обсуждения проектирования у Кона [Kohn 2010] посвящена описанию того, что может пойти не так "в жизни без предваряющего проектирования":

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

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

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

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

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

    3.4 Модели жизненного цикла

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

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

    Модели жизненного цикла, понимаемые в предписывающем смысле, подвергались нападкам, начиная со статьи 1982 года с недвусмысленным заголовком "О вредной концепции жизненного цикла", написанной Мак Кракеном и Джексоном [McCracken 1982]. Школа agile также продолжает обстрел традиционных моделей жизненного цикла, отстаивая более гибкие виды процесса разработки.

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

  • Исторический аргумент. На заре программной индустрии строгие модели жизненного цикла были здоровой реакцией на полностью неформальные подходы, которые можно характеризовать как "раньше код, думать будем потом" или "хакерство" (понимаемое как погружение в код, а не как угроза безопасности в сегодняшнем понимании). Модели жизненного цикла внесли порядок в процесс разработки. Они отражали необходимость разделения деятельности, предшествующей реализации, и деятельности, осуществляемой после построения кода. Сегодня приемы индустрии намного изощреннее, они уходят от простых моделей жизненного цикла – это наблюдение справедливо и для agile методов независимо от присущих им ограничений. Простые модели сыграли свою роль в достижении современного состояния.
  • Концептуальный аргумент. Даже если мы перестанем говорить об анализе, реализации, верификации и проверке правильности как об упорядоченных во времени этапах, то все равно остается полезным понимание этих различающихся видов деятельности.
  • Педагогический аргумент. При обучении программной инженерии удобно объяснять эти виды деятельности, обсуждать идеализированную линейную последовательность выполнения, объяснять, почему успешная разработка ПО требует гибких схем разработки.
  • Остающееся современным обсуждение модели "водопада" связано прежде всего с педагогическим аргументом: модель играет роль контраста, на фоне которого можно убеждать в полезности новых подходов. Эта роль важна. Подумайте о политических науках, где рассматриваются монархия, абсолютизм власти. Вряд ли профессору приходит мысль агитировать за возвращение стиля правления Людовика XIV, но анализ того, почему в свое время люди предпочитали такой стиль управления, какие уроки следует из этого извлечь, необходимы. Все это учит нас применять более современные способы управления.

    Помимо этой роли, "водопад" сегодня дискредитирован и его agile критика вполне корректна.

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

    Обсуждение модели жизненного цикла имеет тенденцию колебания между двумя словами в заголовке книги Зигмунда Фрейда "Тотем и табу". Ни одно из них не подходит. Каждый проект нуждается во временных рамках, предсказании и оценке его прогресса. Это может выполняться более последовательно, приближаясь к идеям "водопада", или более итеративно, в духе Scrum, или некоторой комбинацией этих и других идей. Определение и стандартизация каркаса – только одна из составляющих успеха проекта.

    3.5 RUP – рациональный унифицированный процесс (Rational Unified Process)

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

    Наиболее важный вклад RUP состоит в шести рекомендуемых практиках:

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

    Модель жизненного цикла включает четыре фазы проекта:

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

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

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

    3.6 Модели зрелости

    Модели зрелости, корнями уходя в модели жизненого цикла, переросли их, и занимаются более серьезными проблемами. Все начиналось в восьмидесятых–девяностых годах с введения стандарта ISO 9000 (International Standarts Organization) и программно-ориентированной модели CMM (Capability Maturity Model) – модели технологической зрелости. Эта модель была разработана по заказу министерства обороны США в Институте программной инженерии, размещенном в университете Карнеги МеллонаМодель должна была помочь заказчику оценить качество работ исполнителя, которому министерство предполагало заказать очередной проект.. Позже модель CMM была расширена в семейство моделей, применимых к разнообразным индустриальным дисциплинам. Новая интеграционная модель технологической зрелости – CMMI и будет предметом дальнейшего обсуждения.

    Предупреждение: если вы видели другие презентации CMMI, то, возможно, обнаружите разницу с описанием, представленным ниже. Официальная документация использует ужасную бюрократическую форму. То, для чего понадобились 482 страницы, могло бы быть объяснено на 30. Поэтому нет ничего удивительного, что CMMI отвергают не только сторонники agile, но и многие профессионалы. Я потратил много времени, чтобы пробиться к смыслу и осознать, что, несмотря на всю помпезность, CMMI фактически вводит полезные концепции. В следующем обзоре эти концепции изложены простым языком.

    3.6.1 CMMI простым языком

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

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

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

  • одной из специфических целей является создание базовых линий, где под базовой линией понимается совокупность элементов, подчиняющихся установленному набору правил;
  • одной из специфических практик для этой цели является идентификация элементов конфигурации – определение базисных элементов (программных модулей, тестовых случаев, аппаратуры), которые будут находиться под управлением конфигурации;
  • для этой же цели еще одной практикой является создание системы управления конфигурацией.
  • Здесь есть только несколько универсальных целей. Примером является "процесс узаконен как управляемый процесс", используя термины, имеющие специальный смысл в контексте CMMI. Под управляемым процессом понимается процесс, который планируется в соответствии с четко установленной политикой, обслуживается подготовленным персоналом и является объектом мониторинга. Процесс "узаконен" (институализирован), если он не только используется на практике, но и полностью поддерживается организацией с четкими обязательствами. Универсальной практикой, поддерживающей эту универсальную цель, является "план процесса".

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

    Третий главный аспект CMMI, дополняющий цели и практики, – это оценивание. Модель позволяет организации, разрабатывающей ПО, предоставлять оценку качества соответствующего процесса – процесса, а не продукта! Оценивается только эффект того, как продукт разрабатывается. Любое заключение о качестве того, что производится, должно выводиться неявно. Например, применение CMMI не гарантирует отсутствия дефектов, но позволяет оценить, существуют ли точные процедуры, позволяющие оценить качество продукта, обнаружение дефектов и их отслеживание. В CMMI есть два вида оценивания, каждый с соответствующей шкалой "технологичности" или "зрелости". Непрерывная шкала покрывает оценивание специфических процессных областей, ступенчатая версия оценивает общее состояние процессов организации. В этом обсуждении ограничимся ступенчатым вариантом. Его шкала определяет пять уровней зрелости организации, начиная с наименьшего уровня 1, где практически отсутствует наблюдение за процессами.

    Вы не можете просто объявить миру, что ваша организация является CMMI уровня $$i$$ (для $$i < 1$$). Для получения соответствующего статуса необходимо пройти аттестацию у независимого апробированного оценщика. При этом нельзя пропускать уровни; чтобы получить уровень $$i + 1$$, необходимо иметь уровень $$i$$.

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

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

  • Начальный. Уровень, обычно описываемый в текстах CMMI в отрицательных тонах, напоминающий описание в agile текстах процессов, не принадлежащих миру agile: "процессы обычно нерегламентированные и хаотические. Успех зависит от компетентности и героизма работников. Проверенные процессы не используются".
  • Управляемый. Для проектов определены процессы, поддержанные адекватными ресурсами и обязательствами сопричастников.
  • Определенный. Процессы строго определены соответствующими документами, процедурами и поддержаны инструментарием. Спецификации существуют на уровне всей организации, так что, если процессу потребуется собственный вариант, он будет взят из общей базы.
  • Управляемый на основе количественных данных. В процессах используются численные критерии качества и производительности, оценка производится на основе статистических методов контроля.
  • Оптимизируемый. Процессы включают механизмы собственной оценки и непрерывного улучшения (процессы с обратной связью).
  • Каждый уровень включает некоторые области процесса. Для достижения соответствующего уровня необходимо реализовать соответствующие практики. Например:

  • некоторые области процесса уровня 2: планирование проекта, управление конфигурациями, управление соглашениями с поставщиками;
  • для уровня 3: разработка требований, верификация и проверка правильности, управление рисками;
  • для уровня 4: управление на основе количественных показателей;
  • для уровня 5: анализ и разрешение причин (механизм идентификации причин наблюдаемых недочетов и их устранение).
  • Аспект оценивания в CMMI и его шкала являются наиболее видимой частью подхода. Они, однако, не должны затенять основной вклад: определение каталога универсальных и специфических практик управления.

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

    3.6.2 Персональный программный процесс

    Применять CMMI имеет смысл для организаций, более того, на практике отдача может быть ощутимой для больших организаций. Уотс Хэмфри, бывший менеджер IBM, внесший большой вклад в CMMI, осознал необходимость переноса основных идей CMMI – систематическое применение признанных практик – в рекомендации, позволяющие применять эти практики каждому программисту на уровне его или ее индивидуальной работы вне зависимости от того, сертифицирована его компания или нет. Результатом его усилий стало появление модели PSP – Personal Software Project (ППП – персональный программный проект). Хэмфри ввел также TSP – Team Software Project – модель для команд.

    PSP и TSP не получили широкого отклика, если не считать отрицательных, как обычно, отзывов в agile, но основные идеи заслуживают внимания. Кажется, что с самого начала стоит отвергнуть PSP, поскольку предлагается вышедшая из моды последовательная модель жизненного цикла: план–проект–код–компиляция–тестирование–анализ. Если не считать последней фазы и (сторонники agile, на секунду закройте глаза) первой, то мы не работаем уже по такой схеме. Но главный вклад PSP состоит в другом и не связан с конкретной технологией. Программисту предлагается работать в традициях инженеров: вести журнал событий, делать записи времени работы, записи ошибок и применять статистические методы количественного контроля. Эти советы широко не применяются, зачастую не известны в индустрии. Сегодня в меняющемся технологическом мире изучение PSP полезно для любого программиста.

    3.6.3 CMMI/PSP и agile методы

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

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

  • "могут стандартизовать не лучшие практики, что создает препятствие к изменениям"; но CMMI явно поощряет самосовершенствующиеся процессы, правда, на высшем уровне по шкале CMMI;
  • "эти модели, как это чаще всего реализовано, имеют тенденцию удалять процессы проектирования и принятия важных решений от разработчиков, передавая их под управление центральной организации"; хотя этот феномен действительно существует, ничто не мешает иметь частную модель управления – централизованную или нет; проблема может быть в бюрократической структуре компании, но не связана со структурой модели.
  • CMMI подходит не для всех. Введение CMMI требует определенной решимости, обычно диктуемой нормативными обязательствами или коммерческими интересами в получении сертификата определенного уровня. Возможно, этот кафтан не по вашим плечам. Но если это так и вы находите некоторые agile идеи привлекательными, то возможно комбинирование идей от обеих школ. Существуют отчеты об успешных опытах, один из них, опубликованный Сазерлендом [Sutherland 2010], посвящен использованию Scrum в рамках CMMI уровня 5.

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

    3.6.4 Шкала зрелости agile

    Предсказуемо, что появились публикации, предлагающие "шкалу зрелости agile", содержащую пять уровней, хотя одна из публикаций датирована 1 апреля. Все они напоминают попытку сказать: "Мы тоже зрелые и можем иметь пять уровней, если захотим". (Обзорная статья [Shweigert 2012], первоапрельская – [Ambler 2010].)

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

    Методы agile имеют собственную трехуровневую шкалу, которую можно считать двойником CMMI. Эта шкала получила название Shu–Ha–Ri (или Shuhari), термин, пришедший из японского боевого искусства и обозначающий уровни обучения мастерству. В agile командах так характеризуется уровень мастерства владения методом:

  • состояние Shu означает умение подчиняться; команда должна учиться и применять стандартные рецепты;
  • Состояние Ha означает умение разделять; команда должна уметь абстрагироваться от основных правил и комбинировать их нужным образом;
  • Состояние Ri означает умение превзойти достигнутое; команда может отойти от существующих правил и методов, создавая по мере необходимости свои обственные.
  • Можно вспомнить другую трехуровневую шкалу: бакалавр–магистр–PhDВ России эта шкала, скорее, шестиуровневая: бакалавр–магистр–кандидат наук–доктор наук–член-корреспондент–академик)., лишенную, правда, экзотической привлекательности японских слов Shu–Ha–Ri. (В образовательных кругах подобные идеи лежат в основе популярной пятиуровневой шкалы в модели ДрейфусаПять стадий обучения в модели Дрейфуса: новичок–продвинутый новичок–компетентный специалист–профессионал–эксперт..)

    Параллель с уровнями CMMI ясна; в частности, последний уровень в Shu – Ha – Ri соответствует уровню 5 – "оптимизация" – в CMMI.

    Вернуться к учебному плану