Шаги по разработке большой компьютерной программы для доставки заказчику

Иллюстрация выше — из статьи д-ра Уинстона Ройса «Управление разработкой больших программных систем» 1970 года. Считается, что это первое в программной инженерии описание модели водопада. Диаграммы д-ра Ройса разошлись по сотням учебников и статей. Но часто забывают тот факт, что изобретатель водопада сразу написал: «Эта конкретная реализация рискованна и влечёт за собой неудачу».

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

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

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

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

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

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

Требования меняются. Каждый проект разработки программного обеспечения в какой-то момент столкнётся с этой трудной проблемой.

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

Считается, что первое описание водопада дал д-р Уинстон Ройс в работе «Управление разработкой больших программных систем». Иллюстрации в сотнях работ по программной инженерии, учебниках и статьях являются узнаваемыми диаграммами, которые создал он. Но часто забывается, что в оригинальной статье Ройс также говорит: «[Такая] реализация [на диаграмме] рискованна и влечёт за собой неудачу».

Согласование процесса с окружающей средой


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

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

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


Данный процесс не ограничивается последовательными шагами. Иллюстрация из статьи Уинстона Ройса

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


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

Начните с принятия того, что изменение неизбежно.

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

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

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

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

Изменение процесса для соответствия среде


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

Нет, речь не об этом. Наш тезис в том, что мы можем стать очень эффективными разработчиками, если будем учитывать реалии.

Первая реальность: хотя само совершенство недостижимо, но прагматический успех вполне возможен. Стартап-движение LEAN сделало обычной целью для стартапов MVP, «минимально жизнеспособный продукт». Мы должны распространить эту идею на все разработки и признать, что каждый продукт в действительности является MVP — нашим лучшим приблизительным решением для текущего понимания проблемы.

Вторая реальность заключается в том, что мы не можем реально остановить изменения в требованиях, поэтому нужно работать в таких условиях. Это уже давно понято в реальной разработке: правило Парнаса предусматривает разбиение системы на модули, чтобы повысить гибкость системы в случае внесения изменений. В то же время неоднократно предпринимались попытки описать процессы разработки ПО с последовательными аппроксимациями, то есть процессы инкрементальной разработки (я назвал это методологией «Однажды и навсегда», Once and Future).

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

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

Гибкая разработка идёт на помощь


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

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