Мифический человеко-месяц 45 лет спустя

Впервые о книге Фредерика Брукса я услышал лет десять назад, ещё учась в универе. Её настоятельно советовал почитать наш научный руководитель. Как часто бывает в таких случаях, когда кто-то вам советует что-то почитать, то вы вежливо говорите нечто вроде «да-да, в скором времени, непременно этим займусь», заносите очередной пункт в свой grow list (в лучшем случае) и благополучно об этом забываете.

x453a9mw2vuxjearwchdbuvwlao.png

Через пару лет я вернулся к этой книге и наконец с ней ознакомился. К тому моменту у меня уже было несколько лет работы в IT-индустрии. И когда я начал читать, то удивился, насколько книга, написанная в 1975, да ещё и в сфере разработки ПО, по-прежнему актуальна!

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

Пара слов об авторе книги


ytfin0kzydoxdinkijrexxzhq9o.png Фредерик Брукс был менеджером проекта по созданию IBM OS/360 (группа операционных систем, разработанных IBM для мейнфреймов System/360). Для ускорения разработки он предпринял попытку привлечь ещё больше разработчиков, но решение это оказалось фатальным. Чтобы никто более не наступал на те же грабли, Брукс впоследствии написал серию очерков, которую мы теперь знаем как «Мифический человеко-месяц». Считается, что каждому менеджеру проекта следует ознакомиться с этой книгой.

Высокая кухня требует времени


Именно такой эпиграф предваряет вторую главу книги, а начинается она со слов:

Все программисты — оптимисты.


af135c8d.png

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

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

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

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

Брукс проводит наглядную аналогию между приготовлением еды и разработкой ПО:

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

Также он приводит эмпирическое правило, что написание кода в нашей работе занимает лишь ⅙ от всего времени, которое мы тратим на задачу. Совпадает ли его оценка с вашей?

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

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

Поскольку Брукс сам погорел на этом при разработке IBM OS/360, он сформулировал такой закон:

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


Хирургическая бригада


Третью главу Брукс начинает со следующего утверждения:

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

Продолжая эту мысль, он говорит, что лучше всего небольшая высококлассная команда (не более 10 человек) — чем меньше умов, тем лучше. На ваш взгляд, каков максимально допустимый размер команды?

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

Брукс даже приводит примерный состав команды, расписывая роль каждого её участника.

Итак, какой же состав dreamteam по Бруксу:

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

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


Эффект второй системы


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

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

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

Тут сложно что-либо добавить или опровергнуть. Я с автором полностью согласен. Решением данной проблемы является, на мой взгляд, принцип KISS («keep it simple, stupid»). Потому что в современных реалиях любые попытки угадать дальнейшее развитие системы являются делом неблагодарным.

Пилотная установка

В этом мире нет ничего постоянного, кроме непостоянства.


Нельзя не согласиться
j6gqtawyaccplakg4zp7mcl4tno.jpeg


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

Планируйте выбросить первую версию — вы всё равно это сделаете.


Как вы уже догадались, речь идёт об MVP («minimum viable product»). Это некий прототип, позволяющий проверить ту или иную гипотезу бизнеса. Продолжая предыдущую тему, на этапе MVP следует выключить внутреннего перфекциониста. А уж если результат эксперимента окажется положительным, тогда получится быстрее с нуля написать вторую версию «как положено».

Два шага вперёд и шаг назад


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

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


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

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

И грянул гром


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

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

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

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

Самодокументированные программы


Документацию по работе программы Брукс предлагает встраивать непосредственно в исходный код. Таким образом, это позволит поддерживать документацию всё время в актуальном состоянии. Как только программисту потребуется внести изменения в код, он увидит тут же документацию на этот код и тут же её поправит. Получается, что в 1975 году Брукс предвосхитил нечто такое, что сегодня мы знаем как javadoc. В комментариях он предлагает объяснять не только «как», но и «почему». Назначение является решающим для понимания.

Однако есть и другая точка зрения на этот вопрос. Например, Мартин (Роберт, а не Джордж), автор книги «Чистый код», утверждает, что комментарии — это зло. Даже будучи среди исходного кода они всё равно могут стать неактуальными. «Не трать время на написание комментариев», — говорит Мартин. Вместо этого он предлагает более тщательно подходить к процессу именования переменных, методов и классов. Если всё делается правильно, то и необходимость в комментариях отпадает. А какой точки зрения придерживаетесь вы, документируете ли свой код непосредственно в исходниках?

Модель инкрементальной разработки


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

lugxsqar7r766akbcs_hkcbkc30.jpeg

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

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

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


Зачем понадобилось переиздавать книгу


Тут хотелось бы просто привести цитату Брукса, в которой он иронизирует над самим собой. Он описывает случай, произошедший в самолёте:

Незнакомец, сидевший рядом со мной, читал «Мифический человеко-месяц», и я ждал, как он отреагирует — словом или знаком. Наконец, когда мы вырулили к выходу, я не выдержал:
— Как вам эта книга? Рекомендуете?
— Гм! Ничего такого, чего бы я уже не знал.

Я предпочёл не представляться.


Действительно, зачем переиздавать книгу, которой вот уже 45 лет и которая посвящена такой динамично развивающейся отрасли, как разработка ПО? Весь материал, который я привёл выше, показывает, что многие вопросы, рассматриваемые в книге, актуальны до сих пор. Да, у нас есть scrum, agile, стори-поинты, но если присмотреться, то все новое — забытое, но проявившее себя вновь, старое.

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

© Habrahabr.ru