Любой проект разработки программного обеспечения начинается с великих замыслов и грандиозных планов. Возможно, где-то в альтернативной вселенной существуют проекты, по завершении которых сбываются все мечты, но в нашем мире инициативы разработки ПО далеко не всегда успешно пересекают финишную черту.
Аналитики наверняка могли бы привести статистику по проценту провальных проектов, но она будет неточной, поскольку сам провал определить порой непросто. Например, на выходе вы можете получить отлично работающий код, но им никто не будет пользоваться. А может быть, ваш код даже не будет компилироваться. Иной раз из горящих обломков еще можно спасти что-то полезное, а в других случаях лучше бежать как можно быстрее, пока не прогремел взрыв.
Когда тлеющие развалины остывают, начинаются разбирательства и поиск причин, из-за которых проект пошел под откос. Перечислим самые распространенные.
Слишком маленькая проектная группа
Ясно, что если браться за большой объем работы силами ограниченной группы программистов, то ничего не выйдет. Бывают руководители, которые уверены: чтобы заставить agile-группу работать продуктивнее, нужно начать новый спринт сразу после окончания предыдущего. Никакого отдыха, никаких пауз для обсуждения эффективности используемых методов. Оканчивается сороковой спринт, через минуту начинается следующий. Но такие марафоны закончатся тем, что от вас просто уйдут ценные специалисты.
Разумеется, оценить, сколько именно программистов понадобится, не так просто. Иногда, благодаря тщательной проработке плана, оценки оказываются верными, но могут возникнуть препятствия и помехи. Возможно, руководитель и не виноват в том, что объем работы по ходу реализации удвоился, однако если у вас нехватка людей, ваш проект, скорее всего, обречен.
Слишком большая проектная группа
Избыток участников может обернуться еще более неприятными последствиями, чем недостаток. Те же сетевые эффекты, благодаря которым некоторые социальные сети становятся популярными, для программного проекта могут оказаться губительными. Больше людей – значит больше усилий по координации и больше собраний, отнимающих время. Можно попытаться совсем отменить совещания, чтобы дать программистам больше времени на работу, но тогда можно столкнуться с тем, что API, написанный группой А, не работает с микросервисами, реализованными группой Б.
Если программистов слишком много, проект может намертво застрять из-за подобных задержек. Было бы неплохо, если бы можно было содержать «запасных игроков» на проекте, но обычно денег на это нет.
Радикальные изменения функциональности
Теоретически методы agile-разработки должны обеспечивать скорость и гибкость, но иногда они бессильны – все зависит от масштаба перемен, которые понадобятся. Легко работать в «скором» режиме, когда речь идет о переносе кнопки или изменении цвета в пользовательском интерфейсе. Но когда нужно переработать схему, принципы сегментирования или механизм тиражирования базы данных, легкого пути выполнить «поворот» нет.
Неправильный выбор технологии для проекта
Даже если вы все тщательно спланировали и верно составили перечень функций, проект может провалиться, если для реализации выбрана не та технология. К примеру, базы данных разрабатываются максимально универсальными и гибкими, но имеют архитектурные ограничения. Если вы попытаетесь применять СУБД для задач, на которые она не рассчитана, то при росте масштаба производительность может буквально сойти на нет. Или еще пример: вы начнете проект с базой NoSQL, поскольку это «модно» и современно, а впоследствии выяснится, что вам на самом деле нужны транзакции, строго отвечающие принципам ACID, а NoSQL этого обеспечить не может.
Неверная расстановка приоритетов
Для грамотного планирования требуется составить перечень функций и отсортировать их в порядке приоритетности. Но иногда приоритеты не согласуются с тем, как в реальности реализуются функции. Бывает, что самые важные особенности оказываются и самыми трудными в реализации.
Что в таких ситуациях делать разработчикам? Если они сосредоточатся на самой важной особенности, они не смогут продвигаться вперед и в итоге не закончат вообще ни одной функции. А если начать с самых простых, на выходе можно получить нечто бесполезное.
В процессе планирования нужен не просто контрольный список функций. При разработке архитектуры проекта необходимо принять во внимание возможные трудности и затраты на их преодоление.
Упущенная бизнес-возможность
Иногда в провале виноваты не программисты. Допустим, вы хотите выпустить электронную версию справочника, который в свое время стал бестселлером. Проектная группа создает эффектное приложение, включающее все, что было в справочнике и позволяющее выполнять поиск в интерактивном режиме. Но спросом разработка не пользуется – покупают единицы. Виноваты в этом не программисты – просто сегодня достаточно других источников, и никто не хочет платить за то, что можно быстро найти через поисковик.
Программные проекты могут потерпеть крах без какой-либо вины разработчиков и руководителей. Иногда замысел может казаться прекрасным, но рыночная возможность уже упущена.
Неверные архитектурные решения
Случай из реальной практики: в уже используемой базе понадобилось заменить одну-единственную цифру, чтобы, когда пользователь завершил регистрацию, его идентификационный номер автоматически добавлялся к заказу. Казалось бы, нет ничего проще, но из-за особенностей системы на основе микросервисной архитектуры оказалось, что нельзя просто написать одну строчку кода, обновляющую столбец в базе. В итоге пришлось выстроить целую цепочку взаимодействий микросервисов, для чего понадобилось добавить пять новых вызовов API и, соответственно, написать автоматические тесты для каждого.
Таким образом, по причине неудачных архитектурных решений работа проектной группы может постоянно замедляться даже при элементарных изменениях.
Менять архитектуру может быть непросто, особенно если у ее автора ранимое самолюбие. Однако руководителям проекта необходимо быть готовыми к тому, что первоначальный архитектурный план может в какой-то момент оказаться непригодным и придется вносить коренные изменения. Если руководители не пожелают обращать внимание на провал плана, программисты будут пытаться продолжать выполнять поставленные задачи, с трудом продвигаясь «против течения» из-за неверной архитектурной модели.
Политические конфликты
Попытка обосновать провал технического проекта политическими факторами может выглядеть как перекладывание вины, но это далеко не всегда так. С ростом масштабов проекта и подключением к нему все новых организаций могут появляться разногласия и может начаться борьба различных группировок за контроль, ресурсы и власть.
Противоречия между политическими фракциями нельзя ставить на одну доску с реальными различиями между технологиями. Взять, например, нотации XML и JSON – приверженцы той и другой способны с пеной у рта доказывать, что их вариант лучше, разъясняя его преимущества. Возможно, и те и другие правы, но когда одна часть группы предпочитает XML, а другая – JSON, разногласия неизбежно приведут к расколу.
Подобные ситуации встречаются чаще в последнее время, когда архитекторы стали делить приложения на многочисленные малые сервисы и наборы API. Когда за разные сервисы отвечают разные группы, они не всегда ладят друг с другом. Если группе А нравится JSON, а группа Б предпочитает XML, то в рамках общего проекта придется либо реализовать поддержку обеих нотаций, либо заставить одну из групп изменить предпочтения. В обоих случаях появятся сложности.
Ставка на «сырую» технологию
Программисты любят новейшие инструменты и фреймворки, предпочитая надеяться на то, что в новшестве исправлены все недоработки прошлого и новые библиотеки и абстракции позволят решать задачи быстрее и проще.
Но часто бывает так, что новое поколение системы еще не готово к рабочему применению. Новые функции выглядят мощными и удобными, однако в них возможны недоработки, незаметные на первый взгляд. Например, новая система поддерживает не все нужные типы файлов или взаимодействует лишь с ограниченным числом баз данных. Поддержка других – на подходе, как обещают создатели инструмента, но ваш проект должен быть готов к выпуску уже в текущем месяце, а «на подходе» может означать и полгода, и дольше.
Подобные проблемы могу обречь проект ПО на провал. Группа делает ставку на новую технологию, поскольку она обещает решить серьезные проблемы, и зачастую это обещание оправдывается. Но в какой-то момент, обычно уже на финишной прямой, обнаруживается, что новшеству недостает тех или иных возможностей. Причем это даже может не быть указано в документации – разработчики, конечно, собирались упомянуть о проблеме, но... вы знаете, как это бывает.
Ставка на устаревающую технологию
Разумеется, старые технологии прошли проверку временем и обычно надежнее, однако у них могут отсутствовать функции, которые понадобятся для вашего проекта позднее. Если сделать ставку на устаревающую технологию, вы рискуете остаться без возможности реализовать изменения, которые потребуются в перспективе. Будут появляться новые идеи, протоколы и форматы файлов, а воспользоваться ими не удастся.
Невыполнимые сроки
Эксперты советуют: рассчитайте, сколько времени уйдет на проект, и умножьте на два. Но что они знают, эти эксперты, не написавшие ни строчки кода?
Устанавливать сроки непросто. Часто бывает так, что проект надо сдать к определенному мероприятию. Но когда проект начинают с установки сроков, разработчики еще не в курсе, какие препятствия и помехи их ждут на пути. Потом, если график нарушается и к мероприятию продукт выпустить не удается, проект считается провальным, даже если код работает на отлично. Жестко заданные сроки сдачи помогают участникам работать более собранно и целеустремленно, но могут оказаться невыполнимыми.
Непредвиденное соперничество
Перед тем как браться за проект, безусловно, надо изучить вероятных конкурентов, но предсказать неожиданное появление соперников невозможно. Если новый конкурент реализует функции, которые вам приходится дублировать, см. разделы выше об изменении функциональности и неверных приоритетах.
Склонность торопить события
Многие проекты ПО начинаются с чьего-то замысла по улучшению того или иного существующего сервиса. Инициатор объявляет, что задумал клон Snapchat или Uber для определенных задач, и ждет, что проект будет развиваться так же стремительно, как Snapchat или Uber. Но проблема в том, что оценка масштаба работ, проектирование потоков данных и разработка концепции пользовательского интерфейса зачастую занимают на порядок больше времени, чем написание кода. Однако мечтатели желают перейти от идеи сразу к программированию. (Почему? Может быть, виноваты создатели новых фреймворков, баз данных или «бессерверных» платформ, обещающие, что с их помощью вы сможете создать законченное приложение, написав всего несколько строчек кода.)
Каркасные модели, схемы баз данных и пользовательские истории – это не пустой звук, а важнейшие элементы программного проекта. Полагать, что для реализации идеи достаточно написать код, весьма недальновидно.
Ложные представления о могуществе программного обеспечения
Бывает, инициаторы проектов руководствуются необоснованной верой в то, что ПО способно изменить мир. В свое время многие считали, что социальные сети объединят человечество, но в итоге благодаря им лишь стали еще более заметными и без того очевидные «тектонические разломы». Многие программные проекты начинаются с эффектной презентации, которая обещает революционные изменения в какой-нибудь области. Но когда созданный сервис никаких свершений не приносит, автор впадает в уныние или злится. Он заявляет, что проблема в реализации. При этом неважно, если и приложение, и бэкенд работают безупречно: ведь сервис не принес революционных перемен, на которые все рассчитывали.
Многие программные проекты компилируются, проходят контроль качества, выпускаются и даже получают хорошие отзывы, но совсем не соответствуют тем прекрасным замыслам, о которых говорилось в первоначальной презентации, – просто потому, что они были нереалистичными.
– Peter Wayner. 14 reasons why software projects fail. CIO. June 18, 2018