Руководство господина брукса

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

Эти законы состоят из правил, принципов или известных слов великих и вдохновляющих людей мира разработки. В то же время все они интересные и забавные.

В этой статье вы познакомитесь с одними их самых известных законов в мире разработки.

Закон Мёрфи

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

Всё, что может пойти не так, пойдёт не так.

Первый вывод: если программа работает, возможно, не вы её написали.

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

Итог: компьютер сделает не то, что вы хотите, а то, что напишете.

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

Закон Брукса

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

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

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

Закон Хофштадтера

Этот закон был сформулирован и назван в честь Дугласа Хофштадтера. Он гласит:

Любое дело всегда длится дольше, чем ожидается, даже если учесть закон Хофштадтера.

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

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

Закон Конвея

Любой программный продукт отражает организационную структуру, создавшую его.

Или ещё более ясно:

Организации, проектирующие системы, ограничены дизайном, который копирует структуру коммуникаций в этой организации.

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

Закон Постела или Принцип надёжности

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

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

Принцип Парето или Правило 80/20

Для многих явлений 80 % последствий вытекают из 20 % причин.

Этот принцип стоит за печальной истиной — 80 % багов вытекают из 20 % кода.

Иными словами, 20 % сотрудников выполняют 80 % работы в компании. Проблема в том, что не всегда понятно, какие именно 20 %.

Принцип Питера

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

В иерархической системе каждый индивидуум имеет тенденцию подняться до уровня своей некомпетентности.

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

Принцип Керкгоффса

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

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

Закон Линуса

Названный в честь Линуса Торвальдса, создателя Linux, этот закон гласит:

При достаточном количестве наблюдателей ошибки выплывают на поверхность.

Этот закон был описан с помощью известного эссе «Собор и Базар», в котором объясняется разница между двумя свободными моделями разработки ПО:

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

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

Закон Мура

Мощность компьютеров на единицу стоимости удваивается каждые 24 месяца.

Более популярная версия гласит:

Количество транзисторов интегральной схемы удваивается примерно каждые 18 месяцев.

или

Производительность компьютеров удваивается каждые два года.

Закон Вирта

Программы становятся медленнее куда шустрее, чем компьютеры становятся быстрее.

Как тебе такое, закон Мура?

Правило 90-90

Первые 90 % кода отнимают 90 % времени. Остальные 10 % кода отнимают оставшиеся 90 % времени.

И в итоге получаем 180 %, что подчёркивает сложность оценки времени на разработку.

Принцип оптимизации Кнута

Преждевременная оптимизация — корень всех зол.

Сначала нужно писать код, затем искать узкие места, а затем исправлять их!

Перевод статьи «Famous Laws Of Software Development»

Закон Брукса — Википедия — Brookss law

Закон Брукса это наблюдение о управление программными проектами согласно которому «добавление рабочая сила к позднему программному проекту — позже ».[1][2] Он был придуман Фред Брукс в его книге 1975 года Мифический человеко-месяц. По словам Брукса, добавление в проект человека, который постепенно набирает обороты, требует больше, а не меньше времени.

Пояснения

По словам самого Брукса, закон является «возмутительным упрощением»,[1] но он отражает общее правило. Брукс указывает на основные факторы, объясняющие, почему это работает:

  1. Людям, добавленным в проект, нужно время, чтобы они стали продуктивный. Брукс называет это «наращивать «время. Программные проекты сложны инженерное дело начинания, и новые работники проекта должны сначала получить информацию о работе, которая им предшествовала; это образование требует отвлечения ресурсов, уже работающих над проектом, временно снижая их производительность, пока новые работники еще не вносят значимого вклада. Каждому новому работнику также необходимо интегрироваться с командой, состоящей из нескольких инженеров, которые должны ежедневно обучать нового работника в своей области знаний основам кода. Помимо уменьшения вклада опытных работников (из-за необходимости обучения), новые сотрудники могут даже внести отрицательный вклад, например, если они вносят ошибки, которые отодвигают проект дальше от завершения.
  2. Накладные расходы на коммуникацию возрастают по мере увеличения количества людей. Из-за комбинаторный взрыв, количество различных каналы связи быстро увеличивается с количеством людей.[3] Каждый, кто работает над одной и той же задачей, должен синхронизироваться, поэтому, когда добавляется больше людей, они тратят больше времени, пытаясь выяснить, что делают все остальные.
  3. Добавление большего количества людей к очень делимой задаче, такой как уборка комнат в отеле, уменьшает общую продолжительность задачи (до точки, когда дополнительные работники мешают друг другу). Однако другие задачи, включая многие специальности в программных проектах, менее делимы; Брукс указывает на эту ограниченную делимость другим примером: в то время как одной женщине требуется девять месяцев, чтобы родить одного ребенка, «девять женщин не могут зачать ребенка за один месяц».

Исключения и возможные решения

В законе Брукса есть несколько ключевых моментов, которые позволяют делать исключения и открывают дверь для возможных решений.[4][5]

Во-первых, следует отметить, что закон Брукса применяется только к проектам, которые уже просрочены.[6] Проекты можно вернуть под контроль (или оставить в нем), если люди будут добавлены ранее в процессе.[7] Также важно определить, действительно ли проект задерживается, или график изначально был слишком оптимистичным. Ошибки при составлении расписания приводят к большим задержкам проектов. Корректировка расписания — лучший способ определить точные и надежные временные рамки для завершения проекта.[8]

Также необходимо учитывать количество, качество и роль людей, добавленных в проект. Один простой способ обойти закон о перерасходе проекта — добавить больше людей, чем необходимо, таким образом, чтобы дополнительная мощность компенсировала накладные расходы на обучение и общение.[9] Хороший программисты или могут быть добавлены специалисты с меньшими накладными расходами на обучение.[10] Можно добавлять людей для выполнения других задач, связанных с проектом, например, гарантия качества или документация; при ясной задаче время нарастания минимально.[11]

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

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

В План Бермудских островов, где большинство разработчиков проекта удаляются («отправляются на Бермудские острова»), а оставшиеся остаются для завершения работы над программным обеспечением, было предложено как способ обойти закон Брукса.[12]

Смотрите также

  • Марш смерти
  • Анти-шаблон
  • Закон Линуса
  • Список одноименных законов
  • Список философий разработки программного обеспечения

Примечания

  1. ^ а б Фредерик П. Брукс-младший. Мифический человеко-месяц. 1995 [1975]. Эддисон-Уэсли.
  2. ^ Мэгги Фокс NBC News, 21 октября 2013 г., Лучше пользуйтесь телефоном: почему веб-сайт Obamacare такой провальный. Проверено 21 октября 2013 г. «И отправка слишком большого количества» лучших и самых ярких «тоже может быть неправильным решением, отмечают эксперты по программному обеспечению. Они часто ссылаются на закон Брукса, согласно которому добавление людей в проект замедляет его «.
  3. ^ Джеймс Тейлор, «Руководство по выживанию для менеджеров проектов», 2-е издание, AMACOM[требуется разъяснение ], 2006, ISBN  978-0814408773, п. 21.
  4. ^ «Несмотря на закон Брукса, добавление людей в поздний проект остается обычным делом» … «Я сам много раз проповедовал этот заезженный каштан разработки программного обеспечения, но я больше не думаю, что это правда». (МакКоннелл, 1999)
  5. ^ «Проблема в том, что есть важные исключения, на которые многие люди не тратят время, чтобы учесть их при использовании закона Брукса для оправдания чего-либо». (Беркун, 2006)
  6. ^ «В этих проектах подразумевается, что это применимо только к заключительным этапам проекта. Вопрос в том, как узнать, находитесь ли вы на заключительных этапах проекта?» (Макконнелл, 1999)
  7. ^ «Мы обнаружили, что добавление людей в поздний проект всегда увеличивает его стоимость, но проект не всегда может опаздывать, поскольку может быть достаточно график поглотить их и проект может не быть укомплектованным на максимум. Только при определенной степени последовательных ограничений среди задач проекта реализация проекта будет отложена ». (Hsia, Hsu, Kung, 1999)
  8. ^ Поздние хаотичные проекты, вероятно, будут намного позже, чем думает руководитель проекта — до завершения проекта не три недели, а шесть месяцев. Давай, добавь сотрудников. У вас будет время, чтобы они стали продуктивными. Ваш проект все равно будет позже вашего плана, но это не результат закона Брукса. Это в первую очередь результат недооценки проекта ». (McConnell, 1999)
  9. ^ «Гордон и Лэмб изучили закон Брукса и предположили, что лучший способ оправиться от срыва графика — это добавить больше людей, чем можно было ожидать, и добавить их раньше». (Ся, Сюй, Кунг, 1999)
  10. ^ «Закон предполагает, что все добавленные трудозатраты равны, что неверно. Если бы у меня был выбор — добавить хорошего программиста, который знает кодовую базу и дружит с половиной команды, я бы рассмотрел это». (Беркун, 2006)
  11. ^ «Печальный, но популярный подход состоит в том, чтобы бросить людей без особых объяснений и позволить каждому понять это самостоятельно. Но если менеджер разъясняет, почему Салли и Руперт присоединяются, и определяет для них хорошие роли с участием команды, они» буду настроен на плавный переход «. (Беркун, 2006)
  12. ^ Ши, Том (7 мая 1984). «Разработчики представляют Vaporware»«. InfoWorld. Информационная группа InfoWorld. 6 (19): 48. ISSN  0199-6649. Получено 2010-04-13.

Рекомендации

  • Стив МакКоннелл. «Закон Брукса отменен», IEEE Software, vol. 16, нет. 6, pp. 6–8, Nov / Dec, 1999. Также доступно на сайте авторов (Закон Брукса отменен? ).
  • Пей Ся, Чжи-тунг Сю, Дэвид К. Кунг. «Новый взгляд на закон Брукса: подход системной динамики», compsac, p. 370, Двадцать третья ежегодная международная конференция по компьютерному программному обеспечению и приложениям, 1999 г.
  • Р. Л. Гордон и Дж. К. Лэмб. «Внимательный взгляд на закон Брукса», Datamation, июнь 977 г., стр. 81–86.
  • Беркун, Скотт (11 января 2006 г.). «Исключения из закона Брукса». Получено 2008-07-28.
  • Закон Брукса применим ко многим совместным действиям людей

Культовое эссе Эрика Реймонда «Собор и базар» было опубликовано в 1997 году. Но ни автор, ни критики не анализировали связь разработки свободных программ и классического закона Брукса. Попытаюсь это сделать я.

В 1997 году Эрик Реймонд опубликовал эссе «Собор и базар», мгновенно ставшее поистине культовым. Индекс цитирования этого документа до сих пор зашкаливает за все мыслимые пределы, и происходить это, по-видимому, будет еще долго.

Книга Фредерика Брукса «Мифический человеко-месяц» к тому времени считалась классическим трудом о процессе разработки программ. И один из основных тезисов, выдвинутых Реймондом, гласит, что так называемый закон Брукса неприменим к разработкам, которые делаются через Интернет (например, Fetchmail или ядро Linux).

Ни Реймонд, ни его критики (см., например, Н. Безруков. Повторный взгляд на «Собор и базар»), связь разработки свободных и открытых программ с законом Брукса детальному анализу не подвергали — попытаюсь это сделать я. Примирим, так сказать, огонь и воду.

Закон Брукса

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

Одна из возможных формулировок закона Брукса такова: «Если программистский проект не укладывается в сроки, то добавление рабочей силы только задержит его окончание».

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

Брукс впервые показал, что в группе людей, результат работы которых зависит от действий каждого, значительное количество ресурсов может уходить на обеспечение связей между членами группы и между группами, работающими над различными частями проекта. Количество подобных связей можно посчитать с помощью формулы вида n*(n–1)/2, где n — число членов команды.

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

Linux: торговцы вокруг храма

«Меня очень удивил стиль разработки Линуса Торвальдса — частый выпуск релизов, доступность всех исходных текстов и терпимость к разнородным программам». Это, по Реймонду, и есть «базарный», децентрализованный стиль разработки. Что же происходит при таком подходе?

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

Однако Брукс писал и об этом. В третьей части своей книги он анализирует одну основных трудностей при разработке больших программ. С одной стороны, чтобы обеспечить концептуальное единство проекта, группа должна состоять из малого числа разработчиков, каждый из которых может окинуть взглядом проект в целом. С другой стороны — маленькая группа будет писать операционку класса OS/360 лет двадцать.

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

Если мы посмотрим на разработку программы fetchmail, то увидим, что создавался этот проект «почти по Бруксу». Действительно, «частый выпуск релизов», который Реймонд называет одной из главных причин успеха открытой разработки, — способ обратной связи с массой разработчиков, присылающих патчи. Стихийные разработчики интуитивно, сами того не замечая, воспроизвели что-то вроде «бригады» простейшего образца: один или несколько «хирургов» и неопределенное количество ассистентов. А в случае с ядром Linux количество людей, присылающих патчи, становится неимоверно большим.

Косвенное подтверждение этому можно увидеть в словах Линуса Торвальдса, процитированных в «Соборе…»: «По-моему, не очень существенно, способен ли координатор на оригинальный дизайн. Однако совершенно необходимо, чтобы лидер проекта был способен отличить хороший дизайн от всех остальных». И точно такую же «группу» мы можем увидеть в случае разработки ядра Linux.

Вот он, кстати, тот сакраментальный абзац «Собора и базара», с которого все началось: «В «Мифическом человеко-месяце» Фред Брукс рассматривал различные зависимости времени разработки. Он показывает, что сложность проекта и его коммуникационные издержки квадратично зависят от числа разработчиков, тогда как проделанная работа зависит только линейно. Это утверждение называется законом Брукса, и большинство признает его правильным. Однако если бы дело было только в законе Брукса, Linux не мог бы существовать».

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

Сам Реймонд в «Соборе и базаре» пытается дать стихийным процессам в разработке обоснование с точки зрения психологии: «Джеральд Венберг в «Психологии программирования» предложил теорию, которую мы можем рассматривать как жизненную поправку к закону Брукса. Обсуждая «неэгоистичное программирование» (egoless programming), Венберг замечает, что если разработчики не являются безраздельными владельцами исходников программ и приветствуют, когда другие люди помогают искать ошибки и предлагают различные улучшения, программа прогрессирует намного быстрее». Впоследствии тема связи психологии и теории игр с программированием нашла продолжение в эссе «Заселяя ноосферу».

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

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

Примерно такое же мнение высказал в статье «Повторный взгляд на «Собор и базар» один из критиков Реймонда Николай Безруков. Его статья повествует об этом вопросе более подробно и с большим количеством примеров. Мы же пойдем дальше.

Продолжение статьи — на следующей странице.

GNU: соборы на базаре

…и перейдем от ядра Linux к собственно ОС. Посмотрим теперь, как идет «стихийная» разработка Unix-подобной системы, на примере проекта GNU. Оговорюсь сразу — GNU периода середины-конца девяностых, примерно совпадающего со временем написания «Собора…».

И самое время сейчас вспомнить, что же представляет собой так называемый Unix Way. Под этим выражением обычно понимается системная архитектура, при которой в состав ОС входит множество утилит, причем каждая из них предназначена для выполнения строго своей функции. Другой основополагающий принцип — перенаправление ввода-вывода, благодаря чему эти утилиты могут обмениваться информацией и работать в связках, которые формируются пользователем.

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

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

Также, например, многие утилиты в Linux существуют в нескольких экземплярах. В условиях, когда система строится из «кирпичиков», этот недостаток превращается в достоинство.

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

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

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

Обеспечению концептуального единства проекта Брукс уделяет много внимания в четвертой части своей книги, названной «Аристократия, демократическое и системное проектирование». Эпиграфом к главе стоит цитата из путеводителя по Рейнскому собору, и хотя история об этом умалчивает, но весьма вероятно, что эссе Реймонда обязано своим названием как раз Бруксу. Так вот: разработчики GNU/Linux эту концепцию получили готовой, поскольку занимались, в сущности, повторной реализацией Unix-подобной операционной системы.

Таким образом, разработка программы методом открытых исходников — не панацея, она была применена к изначально стандартному Unix, что позволило уменьшить роль координаторов между отдельными частями проекта: просто осталось реализовать эти стандартные части заново.

Также одной из причин успеха GNU/Linux можно назвать и то, что эта связка первой пришла на массовый рынок и являлась сборником для идей и малых проектов: всегда ведь выгоднее примкнуть к большому проекту, чем затевать свой собственный. Впрочем, здесь уже начинаются скорее психологические проблемы разработки, о которых лучше читать, опять же, у Реймонда.

Выводы

Весьма ценным при разработке открытых программ будет знание того, что законы, по которым велась большая часть подобных разработок до завоевания GNU/Linux теперешней популярности, не вечны, а обязаны своим существованием главным образом специфике реализуемой ОС — в случае с GNU, и вдобавок неограниченному количеству разработчиков — в случае с Linux.

Анализируя вопрос о том, что же представляет собой разработка ядра Linux — «собор» или «базар» (иными словами — централизована ли она или распределена), Николай Безруков высказывает предположение о том, в каком случае какая модель лучше применима: «Для крупных проектов, подобных ОС, особенно важно, чтобы ядро системы разрабатывалось централизованно небольшой тесно сплоченной командой. В то же время при разработке периферийных частей системы более выгоден менее жесткий, более децентрализованный подход».

На первый взгляд может показаться, что это изречение в случае с GNU/Linux на их примере опровергается полностью. Тем не менее мы видим просто путаницу в терминах, вызванную слишком жестким разделением между собой «собора» и «базара».

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

Итак, закон Брукса наконец-то берет свое. Позволю себе предложить несколько путей сглаживания его действия.

В качестве первого пути можно рассматривать «распараллеливание» работы, то есть продолжение Unix Way, но уже в другой форме. Для этого не обязательно, чтобы проект состоял из отдельных утилит, как GNU. Модульной ведь может быть и графическая ОС.

Идея, если честно, была позаимствована у Виктора Вагнера. В статье «True Unix GUI» он описывает концепцию графической оболочки, в которой:

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

Представьте себе графическую ОС, программы которой можно собирать из функций, как из кирпичиков: комбинировать элементы меню, экранные кнопки, просмотровые модули. При этом программирование для нее превращается в разработку отдельных функций, совместную работу которых в связке обеспечивает сама система. Скажем, модуль, который встраивается в текстовый редактор и при выполнении вызывает функцию, реализуемую отдельной динамической библиотекой или даже стандартным скриптовым языком — допустим, awk или perl. То есть задачей просмотрового модуля становится передача системе данных, с которыми он работает, например текстового файла. Задача системы — передать этот файл отдельному скрипту, который выполнит над ним определенное действие, после чего — вернуть просмотрщику. Ничего невозможного с технической точки зрения я в этом не вижу.

Идеология Unix как раз подходит для того, чтобы над текстовым интерфейсом надстроить подчиняющийся сходным законам интерфейс графический, и то, что этого до сих пор не было сделано при разработке какого-либо из оконных менеджеров под X-Window, — как мне кажется, величайшее упущение — ведь графические интерфейсы к текстовым программам существуют давно, та же kppp, например, или графическая «морда» к GNU Chess…

Осталось стандартизировать язык, способы взаимодействия модулей между собой и обмена данными. Как мне кажется, у программистов, занимающихся разработкой под свободными Unix-подобными ОС, есть шанс сотворить что-то похожее. Например, уже сейчас существует язык описания интерфейса XUL (www.mozilla.org/projects/xul), способный стать одной из составных частей нашей гипотетической оболочки. Данные, которыми оперирует система, могут иметь в своей основе метастандарт XML.

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

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

С увеличением количества ПО становится ясно видна тенденция к сокращению числа программистов, работающих над отдельно взятым проектом. Да, исходники открыты, да, можно сделать к ним патч, — но уже ничтожно малый процент пользователей конкретной программы на это способен. Помните, у Честертона отец Браун советовал прятать лист в лесу? Та самая ситуация…

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

Закон Брукса — это наблюдение об управлении проектами программного обеспечения, согласно которому «добавление рабочей силы к позднему проекту программного обеспечения делает его позже». Он был придуман Фредом Бруксом в его книге 1975 года «Мифический человеко-месяц» . По словам Брукса, при определенных условиях добавление нового человека в проект требует больше, а не меньше времени.

Пояснения

По словам самого Брукса, закон — это «возмутительное упрощение», но он отражает общее правило. Брукс указывает на основные факторы, объясняющие, почему это работает:

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

Исключения и возможные решения

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

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

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

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

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

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

Смотрите также

  • Марш смерти
  • Анти-шаблон
  • Закон Линуса
  • Список одноименных законов
  • Список философий разработки программного обеспечения

Примечания

Рекомендации

  • Стив МакКоннелл. «Закон Брукса отменен», IEEE Software, vol. 16, нет. 6, pp. 6–8, Nov / Dec, 1999. Также доступно на сайте авторов ( закон Брукса отменен? ).
  • Пей Ся, Чжи-дун Сю, Дэвид К. Кунг. «Новый взгляд на закон Брукса: подход системной динамики», compsac, p. 370, Двадцать третья ежегодная международная конференция по компьютерному программному обеспечению и приложениям, 1999 г.
  • RL Gordon и JC Lamb. «Внимательный взгляд на закон Брукса», Datamation, июнь 977 г., стр. 81–86.
  • Беркун, Скотт (11 января 2006 г.). «Исключения из закона Брукса» . Проверено 28 июля 2008 .
  • Закон Брукса применим ко многим совместным действиям людей

В EDISON часто обращаются инженеры, желающие добавить сотрудников в команду. Хочется «по-быстрому склепать задачку», воспользовавшись десятком дополнительных разработчиков. Работает ли подобный подход? К сожалению, не всегда. В программировании, как в физике, есть законы.

Собрать толковую команду — настоящее искусство

Закон Брукса

Ни одно обсуждение команд разработчиков не проходит без упоминания данного принципа:

«Добавляя людских ресурсов, мы задерживаем окончание программного проекта» (Брукс, 1975).

Бесчисленные команды разработчиков подтвердили постулат. Законы Брукса и Конвея составляют базу.

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

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

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

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

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

Закон Брукса не означает полный отказ от расширения команд. Но рост объединения редко происходит быстро. Если команда решила расширяться, будет использоваться часть производительности для наращивания мощности.

Ричард Шеридан сделал смелое заявление:

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

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

Методы, описанные автором, заслуживают доверия. Отлично, если закон Брукса будет нарушен.

Закон Конвея

Организации, проектирующие системы, … производят их, копируя структуры коммуникации, сложившиеся в этих организациях,
— Конвей, 1968

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

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

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

Взглянем на систему после 10-ти лет функционирования. Наблюдается обратный закон Конвея:

Предприятия, использующие программные системы… ограничены структурами коммуникации, которые копируют эту систему.

Закон Конвея сообщает о возможном копировании проблем предприятия в интерфейсе: в слоях, или в APL, или в модулях, или где-нибудь ещё.

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

Число Данбара. Природные ориентиры

«Экстраполяция на людей отношений среди обезьян даёт представления о размерах социальных групп. Около 150 особей — предел социальных отношений человека. Количество удостоилось названия «Числа Данбара»,
— Данбар, 2010

Частый вопрос от групп разработчиков: «Насколько большой должна быть команда?» Работа антрополога Робина Данбара дает интересные идеи при попытке ответить на вопрос.

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

Сообщества свыше 150 членов менее сплочённые, требующие повышенного контроля поведения и иерархии. В исследованиях и анализе подчёркиваются основные моменты в формировании групп. Параметр грамотнее назвать «Числами Данбара». Характеристики применимы к различным группам, входящим в состав крупных формирований. Меньшие команды крепче и по предположению опираются на числа с множителем 3.

Следуя тезису, у большинства людей круг близких друзей от 3 до 5 человек. Следующий уровень приятелей от 10 человек до 13–15 (при определенных усилиях). Очередная группа содержит от 30 до 50 — типичный боевой взвод. Популяция в 150 представляет минимальный независимый блок в военной компании и точку создания на предприятиях отдельных группировок.

Данбар предполагает существование формирования в 500 и 1500. Автор поддерживает Платона в определении идеального размера для демократии в 5300 единиц. Можно провести интересные параллели между размерами военных блоков.

Oрганизация Размер
Пожарная дружина 4 или меньше человек
Секция/Отряд 8–12 участников (несколько пожарных дружин)
Взвод 15–30 служащих (2 отряда)
Рота 80–250 солдат (несколько взводов)
Батальон 300–800 бойцов

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

Магическая семерка Миллера (кошелёк Миллера)

Принято считать мудрым выбором размер команды из 7 человек (± 2). Практического смысла в утверждении нет. Доказательства тезиса об оптимальном количестве членов команды в 5–9 человек отсутствуют.

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

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

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

Значимость магии числа 7 под вопросом.

В заключении автор говорит: «Я чувствую, что мой рассказ здесь должен остановиться, т. к. он уже стал достаточно интересным». С публикации статьи Миллера прошло более 50 лет. По общему мнению, диапазон команды 5–9 человек удовлетворителен для управления изменениями. Снизу интервала оправдана необходимость проведения тестов и выполнение требований к команде специалистов. На верхней границе диапазона сложно осуществлять полный контроль системы. Поэтому число сотрудников от 5 до 9 человек имеет смысл.

Описанное количество не отменяет существование команд большего размера в зависимости от обстоятельств.

Размер команды в методологии Scrum

Как статья Миллера об объемах обработки информации человеческим мозгом может применяться к определению размера команды разработчиков ПО? Обратимся к методологии Scrum. В учебнике говорится: «Команда в Scrum должна быть семь плюс или минус два человека» (Димер и др., 2008). Одновременно в руководстве по Scrum за 2011 утверждается: «Команды из более девяти членов вызывают слишком много проблем в координации. Большие команды разработчиков заметно усложняют весь процесс» (Сазерленд и Швабер, 2013).

Учебное пособие гласит:

Роли владельца продукта и руководителя команды Scrum не включены в подсчет, кроме случаев, когда они включаются в работу для сокращения отставания в очередном спринте,

— Сазерленд и Швабер, 2013

Параллельно введение руководителя команды Scrum предполагает, что владелец продукта находится вне команды.

Другие источники дают различные рекомендации по определению членов группы и «просто участвующих».

Команды в диапазоне 4–8 человек видны повсеместно. Статьей Миллера рационально обосновать выбор размеров групп из 7 ± 2. Опыт подтверждает оптимальный предел численности. Количество может быть больше заявленного в источниках по Scrum.

Закон Паркинсона и Закон Хофштадтера

Работа заполняет все время, выделенное для ее выполнения,
— закон Паркинсона

Всегда потребуется больше времени, чем вы ожидаете, даже если вы знаете закон Хофштадтера,
— закон Хофштадтера, 1980

Попробуем ответить на вопрос: «Помните ли вы обучение в ВУЗе? В какой момент реализовывались задания?» Большинство читателей выполняли работу за несколько дней до дедлайна. Часть занималась проектом в ночь перед сдачей.

И подавляющее большинство укладывалось в срок.

Ученые подтверждают: люди плохо справляются с оценкой периода, требующегося на выполнение работы, но преуспевают с решением задачи к четко оговоренной дате (например, Buehler, Гриффин и Peetz, 2010).

При избытке времени на проект происходит чрезмерное расширение объема работ исполнителем.

На разработку программного обеспечения влияют законы Паркинсона и Хофштадтера. Выбирая дату дедлайна, неизбежно возникнет недооценка требуемого времени. В итоге сроки и объем работ увеличатся. Проведенное исследование (Бюлер, Гриффин и Питз, 2010) свидетельствует: оптимизм относительно даты выполнения задачи дает возможность осуществить работу раньше, чем при пессимистичной оценке сроков. Но общее время выполнения проекта оптимистом окажется дольше, чем у пессимиста. Срок дедлайна может быть важнее предполагаемого времени завершения проекта (Арили и Wertenbroch, 2002).

Закон Голла. Парнас и Александер

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

Закон перекликается со словами Дэвида Парнаса:

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

Авторы подчеркивают различные аспекты одного явления, называемого Кристофером Александером «органическим ростом».

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

Принцип может применяться к группам, к ПО:

«Эффективная сложная команда неизменно возникает из простого продуктивного аналога. Сложная команда, собранная с нуля, результативно функционировать не может. И никакие изменения не заставят ее работать. Дело стоит начинать с уже сработавшейся командой».

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

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

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

Законы Келли

Следует добавить пару полезных постулатов от автора статьи.

Масштаб ПО всегда будет увеличиваться пропорционально имеющимся ресурсам,
— первый закон Келли

Внутри каждого большого проекта в области разработки есть маленький побочный проект вне основной задачи
— второй закон Келли

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

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

Вывод

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

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

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

Статья является отрывком из новой книги Аллана Келли «Xanpan книга 2: средство производства». Будет доступна в конце 2015 года.

Мифический человеко-месяц — Википедия

«Мифический человеко-месяц, или Как создаются программные системы» (англ. The Mythical Man-Month: Essays on Software Engineering) — книга Фредерика Брукса об управлении проектами в области разработки программного обеспечения.

Фактически книга Ф. Брукса представляет собой сборник очерков, в которых последовательно обсуждаются узловые проблемы разработки крупных программных проектов: повышение производительности труда программистов, организация коллективной работы, планирование и выполнение графика реализации. Одной из главных тем книги стала идея, получившая впоследствии название «закон Брукса», о том что привнесение в проект новых сил на поздних стадиях разработки лишь отодвигает срок сдачи проекта[1].

Англоязычный журнал PC World поместил книгу Брукса на первое место в списке «Десять IT-книг, которые стыдно признать, что не читал» (Top Ten IT Books Never To Admit You Haven’t Read)[2]. Согласно опросу нескольких тысяч членов сообщества Stack Overflow, книга вошла в десятку наиболее влиятельных книг по программированию всех времён[3]. На сайте библиотеки Ассоциации вычислительной техники книга Брукса характеризуется следующим образом: «Очень мало книг по управлению программными проектами стали столь же влиятельными и неподвластными времени»[4]. По мнению обозревателя Java World Дастина Маркса, «Мифический человеко-месяц» является одной из наиболее известных книг во всей литературе по разработке программного обеспечения, и, вероятно, самой известной книгой в области управления программными проектами[5]. По утверждению журнала Компьютерра о книге Брукса, «в США давно считается, что, не прочитав её, ни один менеджер разработки ПО не сможет действовать эффективно»[6].

Так может быть, прежде чем приступать к новому программному проекту, все-таки имеет смысл почитать Фредерика Брукса?

Наблюдения Брукса основаны на его опыте работы в IBM, полученном в ходе управления проектом по созданию операционной системы OS/360. Для ускорения разработки им была предпринята неудачная попытка привлечения большего числа работников к проекту, сроки по которому уже были сорваны. Заметив свойство менеджеров повторять такие ошибки, Брукс насмешливо называл свою книгу «библией для программной инженерии»: «все её читали, но никто ей не следует!»

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

Книга впервые была опубликована в 1975 году, в 1979 году вышла на русском языке. Юбилейное издание 1995 года (на русском языке — 2000 года) содержит дополнительные главы: эссе «Серебряной пули нет», опубликованное в 1986 г. (глава 16), пересмотр сказанного в этом эссе 10 лет спустя (глава 17) и комментарии автора к его книге через 20 лет после её первого издания (главы 18 и 19).

Программа и программный продукт. Программный продукт отличается от программы:

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

Программный продукт требует в 3 раза больших затрат времени, чем программа (глава 1).

Мифический человеко-месяц. Время выполнения проекта не обратно пропорционально числу программистов, по крайней мере по 2 причинам.

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

Если есть N программистов, то количество пар программистов равно N(N—1)/2, то есть с ростом числа программистов затраты времени на взаимодействие растут квадратично. Поэтому начиная с какого-то N, рост числа программистов замедляет выполнение проекта.

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

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

Хирургические группы. Разумно, если в группе разработчиков есть один «хороший» программист, реализующий самые критические части системы, и несколько других, помогающих ему или реализующих менее критические части. Так делаются хирургические операции. Кроме того, по мнению Брукса, лучшие программисты работают в 5-10 раз быстрее остальных (глава 3).

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

Главный архитектор должен сформулировать свои решения в виде руководства для пользователя (глава 4).

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

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

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

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

Пилотная система. Перед тем, как разрабатывать окончательную систему, необходимо разработать пилотную систему. Пилотная система выявит ошибки в проектировании, после чего она должна быть полностью переделана (глава 11). Эту идею Брукс отвергает через 20 лет в главе 19, так как за 20 лет изменился подход к созданию программ — на место принятой в 60-х—70-х каскадной модели разработки пришла итеративная.

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

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

Снижение стоимости разработки. Брукс приводит 2 способа снизить стоимость разработки программного обеспечения:

  • Нанять программистов только после того, как построена архитектура системы. Иначе при длительности этой стадии, например, в несколько месяцев программистам будет нечего делать.
  • Купить часть программного обеспечения у других разработчиков.
  • Ф. П. Брукс мл. Как проектируются и создаются программные комплексы. (Серия: «Библиотечка программиста») = The Mythical Man-Month. — М.: «Наука», Главная редакция физико-математической литературы, 1979. — 152 с илл. с. — ISBN отсутствует.
  • Фредерик Брукс. Мифический человеко-месяц или как создаются программные системы. (Серия: «Профессионально») = The Mythical Man-Month. Essays on Software Engineering. Anniversary Edition. — СПб.: «Символ-Плюс», 2000. — 304 с.: ил. с. — ISBN 5-93286-005-7.
  • Фредерик П. Брукс. Проектирование процесса проектирования: записки компьютерного эксперта = The Design of Design: Essays from a Computer Scientist. — М.: «Вильямс», 2012. — 464 с. — ISBN 978-5-8459-1792-8.

О «Законе Брукса» при построении IT команд

Всем, кто когда-либо занимался разработкой программного обеспечения, хорошо знаком принцип, впервые сформулированный в 1975 году в эпохальной книге Фреда Брукса «Мифический человеко-месяц», и потому названный «законом Брукса». Вот его крайне упрощенное изложение:

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

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

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

Неопровержимость того, что многочисленный коллектив выполняет меньший объем работы, представляется чуть ли не железным законом человеческой природы. Почему? Чтобы ответить на этот вопрос, нужно разобраться с таким явлением, как ограниченные возможности человеческого мозга. Должно быть, вы слышали о знаменитом эксперименте американского психолога Джорджа Миллера, продемонстрировавшего в 1956 году, что краткосрочная память среднестатистического человека может удерживать одновременно не более семи объектов. Скорее всего, поэтому номера телефонов состоят из семи цифр. Проблема заключается в том, что более позднее исследование доказало ошибочность утверждения Миллера.

Нельсон Коуэн из университета штата Миссури в 2001 году задался вопросом, на самом ли деле магическое правило семи соответствует действительности, и тщательно изучил новые изыскания на эту тему. Оказалось, что число объектов, которые человек может удерживать краткосрочной памяти, не семь — четыре!. Люди часто думают, что могут запомнить больше, используя мнемонические приемы или просто сильнее сконцентрировавшись. Но исследования неуклонно показывают, что мы в состоянии запомнить за один раз лишь четыре фрагмента информации. Видимо, у нашего мозга есть врожденные ограничения на разовое запоминание, и такой вывод отсылает нас снова к Бруксу.

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

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

Количество коммуникационных каналов существенно увеличивается с количеством людей, и наш мозг просто не в состоянии справиться с этим. Если вам нужно вычислить, как влияет размер группы, нужно взять число людей в ней, умножить его на «это число минус один» и разделить на два. Коммуникационные каналы = n (n – 1) / 2. Например, если в группе пять человек, то у вас десять каналов. Шесть человек — пятнадцать каналов. Семь человек — двадцать один канал. Восемь человек — двадцать восемь каналов. Девять человек — тридцать шесть каналов. Десять человек — сорок пять каналов. Наш мозг не в состоянии успевать за таким количеством людей. Мы не можем уследить, чем занимается каждый человек. Начинаем разбираться в этом — и теряем скорость работы.

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

Не поступайте так. Пусть ваши группы остаются малочисленными.

Автор Джефф Сазерленд.
Урывок из книги «Scrum. Революционный метод управления проектами», раздел «Размер имеет значение — но это не то, о чем Вы подумали», стр 80.

Законы программирования / Хабр

Законы, теории, принципы и закономерности, полезные для разработчиков

Введение

Перевод репозитория github.com/dwmkerr/hacker-laws

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

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

Законы

Закон Амдала

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

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

На следующей диаграмме показаны примеры потенциального прироста скорости:

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

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

Теория разбитых окон

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

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

Закон Брукса

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

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

Распространённая присказка «девять женщин не могут родить ребёнка за один месяц» относится к закону Брукса, в частности потому, что некоторые виды работ нельзя разделить или распараллелить.

Это главная тема книги «Мифический человеко-месяц».

Закон Конвея

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

Закон Каннингема

Лучший способ найти правильный ответ в Интернете — не задать вопрос, а разместить заведомо неправильный ответ.

Стивен Макгиди говорит, что в начале 1980-х Уорд Каннингем дал ему совет: «Лучший способ найти правильный ответ в Интернете — не задать вопрос, а разместить заведомо неправильный ответ». Макгиди назвал это «законом Каннингема», хотя сам Каннингем отрицает его авторство и говорит, что его «неверно цитируют». Хотя изначально фраза относилась к общению в Usenet, с тех пор закон использовали для описания работы и других сообществ (Wikipedia, Reddit, Twitter, Facebook).

Число Данбара

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

Точное число таких связей неизвестно. Сам Данбар предполагал, что человек с комфортом может поддерживать не более 150 таких связей. Он описывал его в более социальном контексте: «Количество людей, к которым вы не постесняетесь присоединиться без приглашения, чтобы вместе выпить, если вы случайно столкнётесь с ними в баре». Обычно оценки такого числа разнятся от 100 до 250.

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

Закон Голла

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

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

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

Закон Гудхарта

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

Также часто формулируется как:

Когда мерило становится целью, оно перестаёт быть хорошим мерилом.
Мэрилин Стратерн

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

Примеры:

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

Бритва Хэнлона

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

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

Закон Хофстадера

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

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

Цитата из книги «Гёдель, Эшер, Бах: эта бесконечная гирлянда».

Закон Хатбера

Улучшение эквивалентно разрушению.

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

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

Цикл шумихи и закон Амара

Мы склонны переоценивать влияние технологии в краткосрочной перспективе и недооценивать его в долгосрочной.

Цикл шумихи – визуализация восторгов и развития технологии со временем, изначально построенная компанией Gartner. Лучше всего иллюстрируется графиком:

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

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

Закон Хирама

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

Закон Хирама постулирует, что если у вашего API достаточно много пользователей, для любой из возможных особенностей поведения вашей системы (даже не описанной в публичном контракте) найдётся зависящий от него пользователь. Тривиальным примером могут быть нефункциональные особенности API, типа времени отклика. Более тонкий пример – потребители, полагающиеся на определение типа ошибки посредством применения к её описанию функции regex. Даже если в публичном контракте ничего не сказано по поводу содержания сообщения, и подразумевается, что пользователи должны использовать код ошибки, некоторые из них могут решить использовать сообщение, и изменение сообщения сломает API для этих пользователей.

Закон Кернигана

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

Закон Кернигана назван в честь Брайана Кернигана и взят из книги, написанной им и Плогером: «Элементы стиля программирования».

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

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

Закон Меткалфа

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

Закон основывается на количестве возможных попарных связей внутри системы, и тесно связан с законом Рида. Одлыжко и другие утверждали, что законы Рида и Меткалфа преувеличивают ценность системы, не учитывая ограничения человеческих возможностей понимания сети; см. число Данбара.

Закон Мура

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

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

Закон Мёрфи

Всё, что может пойти не так, пойдёт не так.

Закон Мёрфи, за авторством Эдварда А. Мерфи, постулирует, что всё, что может пойти не так, обязательно пойдёт не так.

Эту поговорку часто используют разработчики. Иногда неожиданные вещи происходят во время разработки, тестирования или даже в продакшене. Его можно связать с чаще употребляемым в Британии законом подлости [собственно, и в России он тоже известен / прим. перев.]:

Если что-то может пойти не так, это случится, причём в наихудший из возможных моментов.

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

Бритва Оккама

Не следует множить сущее без необходимости.

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

Закон Паркинсона

Работа заполняет время, отпущенное на неё.

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

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

Эффект преждевременной оптимизации

Преждевременная оптимизация – корень всех зол.

В работе Дональда Кнута «Структурированное программирование с GoTo» он писал: «Программисты тратят огромное количество времени на размышления и волнения по поводу скорости выполнения некритичных частей программ, и попытки сделать их эффективнее оказывают сильный негативный эффект, если задуматься об их отладке и поддержке. Нам нужно забывать о малозначимой эффективности 97% времени: преждевременная оптимизация – корень всех зол. Однако в критических важных 3% случаев мы не должны упускать наши возможности».

Однако преждевременную оптимизацию также можно описать, как попытку оптимизировать что-то до того, как мы поймём, что нам нужно сделать.

Закон Патта

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

За законом Патта часто следует заключение Патта:

В любой технической иерархии со временем вырабатывается инверсия компетентности.

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

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

Закон Рида

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

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

Закон сохранения сложности (Закон Теслера)

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

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

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

Закон протекающих абстракций

Все нетривиальные абстракции до определенного предела подвержены протеканию.

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

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

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

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

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

Закон тривиальности

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

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

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

Философия Unix

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

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

Модель Spotify

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

Также модель продвигает концепции племён, гильдий, филиалов – других компонентов организационной структуры.

Закон Уодлера

В проектировании любого языка общее время, потраченное на обсуждение особенности из этого списка, пропорционально двойке в степени номера позиции этой особенности в списке.
0. Семантика.
1. Синтаксис.
2. Лексический синтаксис.
3. Лексический синтаксис комментариев.

То есть, на каждый час, потраченный на семантику, приходится 8 часов, потраченных на синтаксис комментариев.

Как и закон тривиальности, закон Уодлера постулирует, что при проектировании языка количество времени, потраченное на структуры языка, непропорционально велико по сравнению с важностью этих структур.

Закон Уитона

Не будь козлом.

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

Принципы

Принципы чаще всего связаны с советами по проектированию программ.

Принцип Дилберта

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

Управленческая концепция, разработанная Скоттом Адамсом (создателем комиксов про Дилберта), вдохновлённая принципом Питера. Согласно принципу Дилберта, сотрудников, которых нельзя было считать компетентными, повышают до управленцев, чтобы ограничить возможный урон компании. Впервые Адамс объяснил этот принцип в статье для Wall Street Journal в 1995 году, а потом подробно описал его в книге 1996 года «Принцип Дилберта».

Принцип Парето (правило 80/20)

По большей части в жизни всё распределяется неравномерно.

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

  • 80% программы можно написать за 20% времени (и на самые сложные 20% уходят остальные 80% времени).
  • 20% усилий дают 80% результата.
  • 20% работы создают 80% прибыли.
  • 20% ошибок приводят к 80% падений программы.
  • 20% функций используется 80% времени.

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

Также этот принцип известен, как правило 80/20, закон важнейшего малого, принцип дефицита факторов.

Примеры: в 2002 году Microsoft сообщила, что после исправления 20% наиболее часто встречающихся ошибок, будет исправлено 80% связанных с ними проблем и падений Windows и Office.

Принцип Питера

В иерархической системе у каждого индивидуума есть тенденция подниматься до уровня своей некомпетентности.

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

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

Принцип надёжности (закон Постела)

Консервативно относитесь к своей деятельности, и либерально ко вкладам других.

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

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

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

SOLID

Акроним, обозначающий следующие 5 принципов:

S: The Single Responsibility Principle [Принцип единственной ответственности]
O: The Open/Closed Principle [Принцип открытости/закрытости]
L: The Liskov Substitution Principle [Принцип подстановки Барбары Лисков]
I: The Interface Segregation Principle [Принцип разделения интерфейса]
D: The Dependency Inversion Principle [Принцип инверсии зависимостей]

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

Принцип единственной ответственности

Каждый объект должен иметь одну ответственность и эта ответственность должна быть полностью инкапсулирована в класс.

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

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

Принцип открытости/закрытости

Программные сущности должны быть открыты для расширения, но закрыты для изменения.

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

Гипотетический пример: представим себе модуль, способный превратить документ в разметке Markdown в документ в разметке HTML. Если модуль можно расширить так, чтобы он научился обрабатывать новые возможности формата Markdown, не изменяя его внутренних функций, тогда модуль открыт для расширения. Если в модуле нельзя изменить обработку текущих функций Markdown, тогда модуль закрыт для изменения.

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

Принцип подстановки Барбары Лисков

Должна быть возможность заменить тип на подтип, не ломая систему.

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

К примеру, у нас есть метод, читающий XML-документ из структуры, обозначающей файл. Если метод использует базовый тип file, тогда в функции должна быть возможность использовать всё, что происходит от файла. Если file поддерживает обратный поиск, и XML-парсер использует эту функцию, но производный тип «сетевой файл» отказывается работать с обратным поиском, то «сетевой файл» нарушает этот принцип.

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

Принцип разделения интерфейса

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

Четвёртый из принципов SOLID. Принцип утверждает, потребители компонента не должны зависеть от функций компонента, которые он не использует.

К примеру, у нас есть метод, читающий XML-документ из структуры, обозначающей файл. Ему нужно только считывать байты, двигаясь вперёд или назад по файлу. Если этот метод придётся обновлять из-за изменений не связанной с ним особенности файловой структуры (к примеру, из-за обновления модели разграничения доступа, представляющей безопасность файла), тогда этот принцип будет нарушен. Файлу лучше реализовать интерфейс «потока с возможностью поиска», а XML-методу – его использовать.

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

Принцип инверсии зависимостей

Модули верхних уровней не должны зависеть от модулей нижних уровней.

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

К примеру, у нас есть программа, читающая метаданные с веб-сайта. Предположительно, её главному компоненту должен быть известен компонент, скачивающий контент веб-страницы, и компонент, считывающий метаданные. Если мы учтём принцип инверсии зависимостей, то главный компонент будет зависеть только от абстрактного компонента, получающего байтовые данные, а он в свою очередь от абстрактного компонента, способного читать метаданные из потока байтов. Главный компонент ничего не будет знать про TCP/IP, HTTP, HTML и т.п.

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

Принцип «не повторяйся» [Don’t repeat yourself]

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

Принцип Don’t repeat yourself, или DRY, помогает разработчикам уменьшить повторяемость кода и держать информацию в одном месте. Он был упомянут в 1999 году Энди Хантом и Дэйвом Томасом в их книге «Прагматичный программист».

Противоположностью принципа DRY [англ. сухой] должен быть принцип WET [англ. мокрый] – «пишите всё дважды» [Write Everything Twice] или «нам нравится печатать» [We Enjoy Typing].

На практике, если одна и та же информация дублируется у вас в двух или более местах, используйте принцип DRY, сливая их в одно место и повторно используя по необходимости.

Принцип KISS

Keep it simple, stupid [Не усложняй, дурик]

Принцип KISS говорит, что большинство систем работают лучше, если их не усложнять; следовательно, простота должна быть ключевой целью в разработке, а ненужной сложности нужно избегать. Зародился он в военно-морском флоте США в 1960, и фразу приписывают авиаконструктору Кларенсу Джонсону.

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

YAGNI

Акроним для You Ain’t Gonna Need It [вам это не понадобится].

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

Автор техники экстремального программирования (XP) и книги «Установленное экстремальное программирование» Рон Джеффрис предполагает, что разработчики должны заниматься реализацией только такой функциональности, которая нужна прямо сейчас, и не пытаться предсказывать будущее, реализуя функциональность, которая может понадобиться позже.

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

Заблуждения распределённых вычислений

Также известны, как заблуждения сетевых вычислений. Это список предположений, касающихся распределённых вычислений, способных привести к отказам в работе ПО. Это следующие предположения:

  1. Сеть надёжна.
  2. Задержка нулевая.
  3. Пропускная способность бесконечна.
  4. Сеть безопасна.
  5. Топология не меняется.
  6. Администратор только один.
  7. Стоимость пересылки нулевая.
  8. Сеть однородна.

Первые четыре перечислили Билл Джой и Том Лион в 1991 году, а Джеймс Гослинг впервые классифицировал их как «Заблуждения сетевых вычислений». Питер Дойч добавил 5, 6 и 7-е заблуждение. В конце 90-х Гослинг добавил 8-е.

Группу инженеров вдохновляли процессы, происходившие в то время в Sun Microsystems.

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

Фактический человеко-месяц / Wrike corporate blog / Habr

У нас в Wrike есть традиция делиться с командой мыслями о книгах, которые прочитали. Мы давно думали, что было бы неплохо распространить эту инициативу и на наш блог на Хабрахабре, и вот подвернулся хороший случай — книга Фредерика Брукса «Мифический человеко-месяц».

Книгу можно назвать скорее классикой фольклора разработки, нежели реальным руководством по построению рабочего процесса. В ней отражены проблемы, с которыми Брукс столкнулся при организации работы над созданием операционной системы OS/360, и его подходы к их решению. Результат был далек от идеала, на что сам Брукс и указывает. Его целью было не научить как правильно, но поднять проблемы, требующие решения. Любопытно разобраться, что изменилось в разработке с 1960-х годов.

Фото из архива IBM

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

История разработки System/360

В начале 1960-х корпорация IBM была абсолютным лидером рынка компьютеров. Ее доля составляла 75%. Однако перспективы становились все менее радужными. Абсолютно все системы IBM были несовместимы между собой. Серии 1401, 1620, 7070 и т. д. были полностью изолированными. Хотите перейти с 1401 на 1620 — купите не только новый процессор, но и всю периферию. Софт тоже придется переписать.

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

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

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

Весь аппаратно-программный комплекс назвали System/360, а операционную систему — OS/360. Иронично, что проблемы обратной совместимости было решено решить за счет отказа от совместимости с предыдущими системами.

Разработка системы заняла существенно больше планируемых сроков, ее стоимость составила не $625 млн, но $5,25 млрд долларов — немногим меньше, чем программа Appollo с ее ракетами, астронавтами и высадкой на Луну за тот же 1965 год. Риск банкротства для IBM был вполне реален, но все обошлось. Анонс системы состоялся 7 апреля 1964 года, а первые продукты были выпущены в середине 1965. Успех был грандиозный. Принцип взаимозаменяемости компонент, заложенный в рамках этой системы, соблюдается и по сей день. К слову, именно после System/360 стандартным размером байта стали 8 бит.

Основные утверждения Брукса

Из предисловия ко второму изданию: «Эта книга является запоздалым ответом на вопросы относительно трудностей разработки программ (“запоздалым” в 1975 году! — прим. авт.). В течение ближайшего десятилетия не возникнет методов программирования, использование которых позволит на порядок повысить производительность разработки при прочих равных условиях».

Среди основных утверждений Брукса, которые стали расхожими, можно отметить следующие:

  1. Программному продукту грозит устаревание еще до его завершения.
  2. Из всех проектируемых систем наибольшую опасность представляет вторая по счету. Обычно ее приходится перепроектировать заново.
  3. Планируйте выбросить первую версию — вам все равно придется это сделать, потому что она не удовлетворит ожидания пользователей.
  4. Нельзя оценивать программные проекты в человеко-месяцах. Человеко-месяц — ошибочное и опасное заблуждение, поскольку он предполагает, что месяцы и количество людей можно менять местами.
  5. Самые лучшие программисты-профессионалы в 10 раз продуктивнее слабых.
  6. Закон Брукса: если проект не укладывается в сроки, то добавление рабочей силы задержит его еще больше.

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

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

Первая и вторая системы 50 лет спустя

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

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

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

Архитектура второй системы получится плохой. Проект System/360 Брукс считает именно второй системой. Специализированные проекты, которые IBM разрабатывала ранее получались вполне неплохими, а вот с 360 они решили все сделать правильно.

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

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

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

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

Относительно того, что при разработке именно программных проектов нельзя манипулировать оценками в человеко-месяцах, Брукс немного лукавит. На самом деле так нельзя делать в любом проекте.

Планирование сроков и ресурсов проекта — нехитрое по сути дело. Если знать все задачи, зависимости между ними, оценки сроков и необходимые ресурсы, то все вполне просто. Только ленивый не справится с созданием плана в таких условиях. Но даже в этом случае нельзя бесконечно добавлять людей, чтобы ускорить проект. Всегда есть критический путь который определяет минимально возможные сроки, вне зависимости от количества ресурсов. Подробнее об этом, см. «Управление проектами в СССР (1976)» и «Критическая цепь».

К сожалению, условия необходимые для осуществления планирования не всегда выполняются. В этом случае составить корректный план невозможно. Даже оценки сроков выполнения отдельных задач всегда получаются из практического опыта. Но что если такого опыта нет? Завязать шнурки — минутное дело, вернее 5-7 секунд. Завязывая шнурки каждый день, мы можем из своего опыта достаточно точно оценить, сколько времени нам потребуется на выполнение этой же работы завтра. Но попробуйте предсказать, сколько времени у вас займет завязать шнурки одной рукой. Совпадут ли ваши оценки с реальным опытом? Любопытный эксперимент. Подробнее — Robert C. Martin «Effective Estimation (or: How not to Lie)».

Мы очень плохи в планировании того, что никогда не делали, любых новых инициатив, не только программной разработки. Именно в такой ситуации оказался Брукс, когда его попросили составить план проекта, а также оценку сроков и стоимости разработки System/360.

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

Однако краткосрочное планирование вполне реально. Если планировать итерации на 2-4 недели, это можно делать достаточно точно. Со временем нарабатывается навык декомпозиции крупных задач на более мелкие, а небольшие задачи оценить проще. Кроме того, постоянно работая в одном направлении, человек накапливает экспертизу. Задачи, которые три месяца назад казались совершенно новыми, так что их можно было оценивать только пальцем в небо, оказываются вполне похожими на недавние. Значит, и оценки их сроков будут аналогичными.

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

Что Брукс упустил

— Мистер Брукс, вы сказали, что на проект вам потребуется два года и $625 млн, прошло уже два с половиной, вы вдвое превысили бюджет, но результатов нет. Мистер Брукс, вы понимаете, что успех всей компании зависит от скорейшего завершения вашего проекта? Мы выделяем вам еще $2 млрд и наймем вам дополнительно 500 человек.
— Мистер Брукс, ваша задача завершить все необходимые работы в течение следующего года.

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

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

Реальная проблема Брукса не в том, что на выполнение его проекта потребовалось четыре года, и не то что бюджет составил $5 млрд., а в том, что он не смог заранее точно спланировать ни сроки, ни бюджет. Фактически он ошибся в 10 раз. Конечно, Брукс ищет способ как ускорить разработку в те же 10 раз, но это не решение.

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

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

Все могло бы повернуться иначе, если бы в начале проекта Брукс настоял на том, что бюджет проекта может составить от $1 до $6 млрд., а длительность от 3 до 7 лет, и дать более точных оценок невозможно. А руководство IBM, в свою очередь, признало эти оценки.

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

Закон Брукса Википедия

«Мифический человеко-месяц, или Как создаются программные системы» (англ. The Mythical Man-Month: Essays on Software Engineering) — книга Фредерика Брукса об управлении проектами в области разработки программного обеспечения.

Фактически книга Ф. Брукса представляет собой сборник очерков, в которых последовательно обсуждаются узловые проблемы разработки крупных программных проектов: повышение производительности труда программистов, организация коллективной работы, планирование и выполнение графика реализации. Одной из главных тем книги стала идея, получившая впоследствии название «закон Брукса», о том что привнесение в проект новых сил на поздних стадиях разработки лишь отодвигает срок сдачи проекта[1].

Англоязычный журнал PC World поместил книгу Брукса на первое место в списке «Десять IT-книг, которые стыдно признать, что не читал» (Top Ten IT Books Never To Admit You Haven’t Read)[2]. Согласно опросу нескольких тысяч членов сообщества Stack Overflow, книга вошла в десятку наиболее влиятельных книг по программированию всех времён[3]. На сайте библиотеки Ассоциации вычислительной техники книга Брукса характеризуется следующим образом: «Очень мало книг по управлению программными проектами стали столь же влиятельными и неподвластными времени»[4]. По мнению обозревателя Java World Дастина Маркса, «Мифический человеко-месяц» является одной из наиболее известных книг во всей литературе по разработке программного обеспечения, и, вероятно, самой известной книгой в области управления программными проектами[5]. По утверждению журнала Компьютерра о книге Брукса, «в США давно считается, что, не прочитав её, ни один менеджер разработки ПО не сможет действовать эффективно»[6].

История написания и изданий

Так может быть, прежде чем приступать к новому программному проекту, все-таки имеет смысл почитать Фредерика Брукса?

Наблюдения Брукса основаны на его опыте работы в IBM, полученном в ходе управления проектом по созданию операционной системы OS/360. Для ускорения разработки им была предпринята неудачная попытка привлечения большего числа работников к проекту, сроки по которому уже были сорваны. Заметив свойство менеджеров повторять такие ошибки, Брукс насмешливо называл свою книгу «библией для программной инженерии»: «все её читали, но никто ей не следует!»

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

Книга впервые была опубликована в 1975 году, в 1979 году вышла на русском языке. Юбилейное издание 1995 года (на русском языке — 2000 года) содержит дополнительные главы: эссе «Серебряной пули нет», опубликованное в 1986 г. (глава 16), пересмотр сказанного в этом эссе 10 лет спустя (глава 17) и комментарии автора к его книге через 20 лет после её первого издания (главы 18 и 19).

Основные идеи

Программа и программный продукт. Программный продукт отличается от программы:

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

Программный продукт требует в 3 раза больших затрат времени, чем программа (глава 1).

Мифический человеко-месяц. Время выполнения проекта не обратно пропорционально числу программистов, по крайней мере по 2 причинам.

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

Если есть N программистов, то количество пар программистов равно N(N—1)/2, то есть с ростом числа программистов затраты времени на взаимодействие растут квадратично. Поэтому начиная с какого-то N, рост числа программистов замедляет выполнение проекта.

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

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

Хирургические группы. Разумно, если в группе разработчиков есть один «хороший» программист, реализующий самые критические части системы, и несколько других, помогающих ему или реализующих менее критические части. Так делаются хирургические операции. Кроме того, по мнению Брукса, лучшие программисты работают в 5-10 раз быстрее остальных (глава 3).

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

Главный архитектор должен сформулировать свои решения в виде руководства для пользователя (глава 4).

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

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

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

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

Пилотная система. Перед тем, как разрабатывать окончательную систему, необходимо разработать пилотную систему. Пилотная система выявит ошибки в проектировании, после чего она должна быть полностью переделана (глава 11). Эту идею Брукс отвергает через 20 лет в главе 19, так как за 20 лет изменился подход к созданию программ — на место принятой в 60-х—70-х каскадной модели разработки пришла итеративная.

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

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

Снижение стоимости разработки. Брукс приводит 2 способа снизить стоимость разработки программного обеспечения:

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

Примечания

Литература

  • Ф. П. Брукс мл. Как проектируются и создаются программные комплексы. (Серия: «Библиотечка программиста») = The Mythical Man-Month. — М.: «Наука», Главная редакция физико-математической литературы, 1979. — 152 с илл. с. — ISBN отсутствует.
  • Фредерик Брукс. Мифический человеко-месяц или как создаются программные системы. (Серия: «Профессионально») = The Mythical Man-Month. Essays on Software Engineering. Anniversary Edition. — СПб.: «Символ-Плюс», 2000. — 304 с.: ил. с. — ISBN 5-93286-005-7.
  • Фредерик П. Брукс. Проектирование процесса проектирования: записки компьютерного эксперта = The Design of Design: Essays from a Computer Scientist. — М.: «Вильямс», 2012. — 464 с. — ISBN 978-5-8459-1792-8.

Ссылки

Обзор книги «Мифический человеко-месяц» — Школа программирования ProgTips

Книга Фредерика Брукса «Мифический человеко-месяц, или Как создаются программные системы» — это книга обязательная к прочтению для каждого программиста. Она вышла еще в 1975 году, но совершенно не утратила своей актуальности.

Мне эта книга повстречалась очень вовремя. Я только что закончил ВУЗ и начал работать программистом. Вначале было очень трудно. Книг по IT тогда было мало. Эту книгу я читал в библиотеке, она была изрядно потрепана. И я поразился, сколько ценного она содержит. Советы Брукса очень помогли мне в начале карьеры. А особенно эта книга пригодилась, когда я сам стал руководить программистами.

Фредерикс Брукс работал в IBM и руководил созданием операционной системы System/360. На тот момент — это был самый крупный программный проект в мире. В процессе работы возникли неожиданные сложности. Брукс был наблюдательным человеком и сумел понять природу этих сложностей. Он сумел сформулировать основные принципы разработки ПО, которые отличают программирование от других отраслей производства.

Что же это за принципы?

Закон Брукса

Главный вывод, который он назвал законом Брукса гласит:

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

Этот закон обычно иллюстрируют так: «Даже если собрать девять женщин, то они не смогут родить ребенка за месяц».

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

Метод Вирта

Согласно Бруксу лучший метод разработки ПО — это метод Никлауса Вирта, автора языка Паскаль.

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

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

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

ООП — это болезнь

В этой книге я впервые прочитал критическое мнение о модной в те времена объектно-ориентированной технологии разработки программ.

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

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

Исправления портят программу

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

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

Гораздо лучше четко сформулировать требования к программе и реализовать их. Чтобы программа делала что-то одно, но делала это хорошо.

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

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

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

В одном из исследований Сакман (Sackman), Эриксон (Erikson) и Грант (Grant) измеряли производительность труда в группе опытных программистов. Внутри одной лишь этой группы соотношение между лучшими и худшими результатами составило примерно 10:1 по производительности труда и 5:1 по скорости работы программ и требуемой для них памяти! Короче, программист, зарабатывающий 20 тысяч долларов в год, может быть в десять раз продуктивнее программиста, зарабатывающего 10 тысяч долларов.

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

Серебряной пули нет

Самый интересный прогноз Брукса о том, что в ближайшее время не будет технологий, способных на порядок увеличить скорость разработки. Прошло уже очень много лет, а прогноз Брукса полностью сбылся. Как и сорок лет назад программисты пишут программы вручную. Нет технологии, в которую засунешь ТЗ заказчика, а она выплюнет готовый код.

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

Понравилась статья? Поделить с друзьями:
  • Руководство к станку dk7740
  • Официальное руководство cisco по подготовке к сертификационным экзаменам ccent ccna icnd1 100 105
  • Mut meccanica tovo spa mod sf 25 m1s инструкция
  • Хендай соната dn8 руководство по эксплуатации
  • Руководство ссаными тряпками