Остров, о котором забыл Scrum

ПрограммированиеСовершенный код
Автор оригинала: Bob Martin
На оригинал данной статьи я наткнулся случайно, разгребая почту и наткнувшись на новостную рассылку от ScrumAlliance. Тема метрик Scrum команд и непосредственно кода, меня интересует уже давно. Особенно любопытно, что с этими метриками делать дальше, и первостепенно — зачем они вообще нужны?

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

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


The Land that Scrum Forgot



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

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

Scrum дает вам быстрый старт! Это отлично. Часто первые спринты сталкиваются с первыми особенностями Scrum'а. Менеджеры и заказчики счастливы. Команда работает блестяще, и она тоже счастлива. Все счастливы и видят в Scrum огромный успех.

Это повторяется в следующей и в следующем за ним спринте. Производительность высока. Система постепенно строится, а весь функционал уже работает. Ожидания созданы. Планы построены. Энтузиазм парит над Scrum. Достигнута гиперпродуктивность!

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

Но код растет быстро; и когда кодовая база становится больше, ее становится тяжело поддерживать. Программисты значительно замедляются из-за ухудшения кода. Команды «сдуваются» до невозможного из-за огромного груза плохо написанной системы. Если об этом не позаботились заранее, гиперпродуктивная Scrum команда впадает в болезнь, которая убивает множество софтверных проектов. Они породили беспорядок (Прим. пер.: mess).

«Подождите!» — слышу как говорите вы. «Я думал что Scrum нужен чтобы усилить команду! Я полагал, что команда сделает все возможное, чтобы удостовериться в качестве. Я думал, что укрепленная Scrum команда не создаст бардак!»

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

Здесь нет ответа. Причина в том, что scrum команда создает беспорядок, потому что она укреплена и стимулирована его создавать. И Scrum команда может создавать его быстро, очень-очень быстро! Scrum команда гиперпродуктивна по части создания бардака. Пока вы не знаете об этом, беспорядок будет становиться «таким большим и таким глубоким, таким высоким, что вы не сможете его устранить. Выхода нет».

И когда это наступает, продуктивность падает. Мораль падает. Заказчики и менеджеры становятся злыми. Жизнь плоха.

Так как же стимулировать Scrum команду, чтобы она не делала беспорядка? Можем ли мы просто попросить не создавать его? Мы пробовали. Это не работает. Стимуляция работать быстрее основана на осязаемости результата. Но наградить команду за хороший код, если вы не знаете способа объективно оценить его, невозможно. Без однозначного способа измерить беспорядок, его нельзя прекратить создавать.

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

Мы можем измерить беспорядок, внедряя инженерные дисциплины и практики, как например разработка через тесты (TDD), непрерывная интеграция (Continuous Integration), парное программирование, коллективное владение кодом и рефакторинг; т.е. инженерные практики экстремального программирования (XP).

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

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

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

Программисты, практикующие TDD создают большое количество автоматически тестов, которые поддерживают друг друга и являются регрессионным набором. Это то, что вы можете измерить! Измеряйте покрытие. Измеряйте число тестов. Измеряйте количество новых тестов в спринте. Измеряйте количество дефектов, о которых сообщается в каждом спринте и используйте это чтобы определить адекватность покрытия кода тестами (Прим. пер.: the test coverage).

Задача в том, чтобы повысить уверенность в наборе тестов до такого состояния, чтобы вы могли доставлять продукт (Прим. пер.: deploy the product) сразу, как набор тестов прошел. Поэтому измеряйте количество «других» тестов, которые как вы считаете необходимо проводить, и сделайте сокращение их количества приоритетным; особенно если это ручные тесты!

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

Недокументированные системы, или системы, где документация не актуализирована в соответствии с продуктовым кодом (Прим. пер.: production code) беспорядочны. Модульные тесты, получаемые в ходе TDD являются документами, описывающими низкоуровневую архитектуру системы. Каждый программист, которому требуется знать как так или иная часть системы работает, может полагаться на чтение тестов, как на однозначное точное описание. Эти документы никогда не потеряют актуальность, до тех пор пока они отрабатывают.

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

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

Измеряйте хрупкость тестов (Прим. пер.: test breakage). Тесты должны быть разработаны таким образом, чтобы изменения в продуктовом коде приводили к небольшим поломкам тестов. Если большая часть тестов падает, когда изменяется продуктовый код, то тесты требуют рефакторинга (Прим. пер. test design needs improving).

Измеряйте Цикломатическую сложность. Функции, которые очень сложны (например, cc > 6 или близко к этому) должны быть подвергнуты рефакторингу. Используйте средства наподобие Crap4J, чтобы определить методы и функции, нарушающие это правило и имеющие наименьшее покрытие тестами.

Измеряйте размер функций и классов. Средняя функция должна иметь менее 10 строк кода. Функции длиннее 20 строк надо разбивать. Классы более 500 строк следует разбивать на два и более классов. Измеряйте корреляцию Брейтвэйта, она должна иметь значение более 2.

Измеряйте метрики зависимостей. Убедитесь, что нет циклических зависимостей. Убеждайтесь, что поток зависимостей идет в направлении абстрагирования, в соответствии с принципом обращения зависимостей и принципом стабильных абстракций (Прим. Принцип стабильных абстракций: пакеты, которые максимально неизменчивы, должны быть максимально абстрактными. Изменчивые пакеты должны быть конкретными. Абстрагированность пакета должна быть пропорциональна его изменчивости.).

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

Внедрите непрерывную интеграцию. Настройте билд-сервер наподобие Hudson, Team City или Bamboo. Пусть сервер собирает систему каждый раз, когда разработчик добавляет код (Прим. пер.: commits some code). Прогоняйте все тесты на этой сборке и устраняйте неисправности непременно.

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

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

Истории тестирования (Прим. пер.:Story tests) это высокоуровневые документы, разрабатываемые бизнес-аналитиками и тестировщиками. Они описывают поведение системы с точки зрения заказчика. Эти тесты, написанные с помощью средств наподобие FitNesse или Cucumber, это требования которые надо соблюдать. Когда эти тесты прошли, команда знает что она закончила истории, которые этими тестами описаны.

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

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

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

Как охранять Scrum команду от снижения продуктивности? Как быть уверенным в том, что гиперпродуктивность не завязнет в трясине? Убеждайтесь в том, что гиперпродуктивная команда не создает беспорядка! Убеждайтесь в том, что они используют практики, которые порождают измеримый результат. Используйте этот результат, чтобы измерять качество кода, который команда создает; и стимулируйте поддержание этого кода чистым.
Теги:метрикипродуктивностьscrumэкстремальное программирование
Хабы: Программирование Совершенный код
+24
21,9k 173
Комментарии 52

Похожие публикации

Middle | High middle front-end разработчик (React + Typescript)
от 80 000 до 160 000 ₽CSSSRМожно удаленно
Программист C# (Senior)
от 180 000 ₽ГК «Системные Технологии»КалининградМожно удаленно
Senior system developer/ С++
от 170 000 ₽GETMOBITМосква
Embedded C Разработчик / Embedded C Software Developer
от 100 000 ₽Flipper Devices Inc.МоскваМожно удаленно

Лучшие публикации за сутки