![](https://habrastorage.org/webt/mo/xe/1y/moxe1ykfdvqgrjlvi--a0cxdbt0.jpeg)
От переводчика:
Начало года — отличное время, чтобы вдумчиво оценить прошедший год. Окинуть широким взглядом происходящее и понять, как сделать 2019 год лучше, спокойнее и продуктивнее. В этом деле нам показалась полезной статья How To Slow Down to Go Faster Than Ever in Software Development, которую написал Lemi Orhan Ergin. А ее перевод мы публикуем ниже.
Основные тезисы:
- Спешка не делает нас быстрее или эффективнее; она увеличивает стресс и лишает возможности сфокусироваться. Вместо спешки нужны творческий подход, эффективность и сфокусированность.
- Нанимайте самых талантливых специалистов, работайте сообща, практикуйтесь и учитесь вместе. Так вы повысите профессионализм и создадите культуру мастерства в компании.
- Наращивайте гибкость команды и эффективность процессов, составляя планы и регулярно сверяясь с ними. Находите, анализируйте и устраняйте любые источники пустых трат времени.
- Вы не можете быть гибкими без качественной кодовой базы. Устраняйте дефекты, чаще выпускайте версии, пишите тесты до написания основного кода, проводите рефакторинг, сосредоточьтесь на простом дизайне.
- Работающее ПО не означает качественно разработанное. Только настоящие профессионалы могут построить добротное программное обеспечение, которое позволит вам развиваться максимально быстро.
Максимально быстрое выполнение задач может стать вашим врагом, если заниматься разработкой бесконтрольно. Есть три важных области, в которых стоит замедлиться: люди, процесс и продукт. Прежде чем погружаться в детали, позвольте рассказать вам историю.
Насколько я помню, это был 2011 год. Я присоединился к команде, которая создавала платформу для онлайн маркетинга. Моей основной задачей было добавлять новые фичи настолько быстро, насколько могу. Я ведь был senior developer-ом. Мы называем разработчиков «senior», когда они разрабатывают быстрее, чем другие, верно? Однако, когда я приступил к работе, мы заметили, что работать быстро практически невозможно из-за технического долга и недочетов в дизайне системы. Мы также заметили, что с каждой попыткой ускориться мы увеличиваем сложность и уничтожаем качество. Я пришел к выводу, что единственный способ ускориться – переписать систему с нуля.
Я помню, как во время телефонного разговора с product-менеджером я сказал, что нам необходимо переписать всю систему. После 30 секунд молчания менеджер спросил: «Ты говоришь, что твоя команда разработала продукт настолько низкого качества, что теперь эта же самая команда должна переписать этот же продукт заново, но на этот раз сделать лучше. Верно? Прости, но это неприемлемо. Вы должны были писать его лучше сразу.»
Зомби-ПО нуждается в переписывании, снова и снова
В соответствии с докладом Standish Group’s Chaos Report, 94% проектов переделывались с нуля более одного раза. Это огромная цифра. Вспоминая проекты, над которыми я работал, я понимаю, что практически все они были переписаны с нуля на новых технологиях, с новыми архитектурой и дизайном. Переписывание с нуля — настолько типичное явление для нашей отрасли, что нередко компании рассматривают его как единственный способ развития и управления проектом. Сначала мы пишем, а потом переписываем и переписываем, снова и снова.
Нам необходимо знать своих главных врагов. Скорость – это жизненно необходимое качество при разработке программного обеспечения. Важно не только выйти первым на рынок, но и быстро реагировать на отзывы клиентов, добавлять возможности и устранять баги, чтобы пользователи были довольны продуктом.
Но у всех нас есть проблемы с понятием «скорости». Мы полагаем, что быстрое движение вперед и разумные и эффективные действия как-то связаны с выставлением дедлайнов. Мы думаем, что результат будет достигнут быстрее, если больше работать или привлечь больше людей. Как следствие, мы либо добавляем новых людей в проект, либо работаем сверхурочно, чтобы ускорить работу. Спешка не делает нас ни быстрее, ни продуктивнее. Спешка создает стрессовую обстановку, лишает нас возможности сосредоточиться на работе и уничтожает продуктивность. Нужны же творческий подход, эффективность и сосредоточенность.
Разработка ПО – это чертовски сложное дело. Мы не можем избавиться от этой сложности. Следовательно, нам нужно жить с ней. Требование работать быстро создает неустойчивую, неспокойную атмосферу, погружает нас в стресс, лишает возможности работать продуктивно и сосредоточенно. Такой подход просто не работает.
Производительность команды (capacity), генеральный план, оценки трудозатрат, фиксированные рабочие часы, дедлайны и скорость команды (team velocity) — все это иллюзорно. Некомпетентность реальна. Скорость поставки напрямую зависит от профессионализма людей, эффективности процессов и качества выполненной работы. Чаще всего, разработчики сами выставляют себе внутренние дедлайны, даже если в этом нет никакой необходимости.
Как результат, мы получаем legacy-систему. Давление сроков в сочетании с некомпетентностью ведут к legacy-коду – тупику дальнейшего развития системы. Раньше я использовал другое название для legacy-систем – зомби-ПО. Такое определение подходит лучше, поскольку legacy – это буквально мертвое ПО, но которое выглядит работающим на production. Оно работает и даже приносит деньги, но требует крови, жизней и энергии разработчиков, чтобы хоть как-то работать дальше. Разработчики боятся прикасаться к коду, который работает, никто не хочет его развивать.
Robert C. Martin отлично высказался по поводу legacy-систем в своем twitter: «Если ваше ПО становится все сложнее и сложнее разрабатывать, вы что-то делаете неправильно». Работая в спешке, мы настолько снижаем качество, что с каждым шагом работа замедляется все сильнее. Я уверен: единственный способ разрабатывать быстрее – замедлять процесс, пока мы не достигнем стабильности.
Спешка при разработке ПО — зло
В одной из серий CleanCoders Robert C. Martin сказал: «Главная ценность ПО – это способность системы приспособиться к будущим изменениям и упростить их внесение». Спешка – это зло при разработке ПО. Любая попытка поторопиться приведет к серьезному падению продуктивности, сфокусированности, эффективности людей, приспособленности к изменениям и гибкости ПО.
Например, у нас всегда есть время исправлять баги, но нет времени писать тесты. Мы не проводим рефакторинг и не пишем тесты, потому что у нас мало времени. Но зато у нас всегда находится время на отладку, вбивание костылей и исправление багов.
Мы настолько сосредоточены на процессе, что нередко забываем о самом ценном для разработки ПО – людях. Процессы помогают людям сделать продукт более высокого качества, поднимают мотивацию и культивируют здоровую рабочую обстановку. В конечном счете эффективность процесса важна, но нет ничего ценнее людей.
Необходимо понять, что никто и ничто не идеальны. Заказчики, руководители, менеджеры, члены команды, представители бизнеса, даже вы – все не идеальны. Требования, документация, инструменты, код, разрабатываемая система и ее дизайн также никогда не будут идеальными. Значит, мы должны перестать спешить и бездумно ускорять разработку. Единственный способ двигаться быстрее в устойчивом темпе – замедлиться в трех важных направлениях:
- Люди – повышение профессионализма и мастерства,
- Процесс – улучшение гибкости и эффективности,
- Продукт – улучшение качества и автоматизация.
Где замедлиться, если речь идет о людях
Процессы и инструменты не создают продукт. Это делают люди. Стоит признать, что «найм талантов» – наиболее важная задача компании, имеющая прямое влияние на будущее компании в целом и создаваемого продукта в частности.
Нанимайте в свою организацию самых талантливых. Говоря «самых», я не имею в виду умнейших и самых опытных. Я ищу, как минимум, увлеченных, дисциплинированных и мотивированных. Если человеку присущи эти три качества, он с легкостью разовьет свои таланты.
Найм должен быть выгоден обеим сторонам. Поэтому замедлите процесс найма и потратьте время на его улучшение. Люди присоединяются к компаниям, в которые верят. Смоделируйте, каких людей вы ожидаете увидеть в своей команде. И сделайте так, чтобы талантливые люди поверили в вас, глядя на вашу культуру, ваше представление о будущем и ваших сотрудников.
Эго – это яд, который медленно убивает вашу организацию. Никогда не позволяйте ему проникнуть в вашу организацию. Начиная от приятных в общении дураков и заканчивая гениальными придурками – не позволяйте крайностям становиться частью вашей команды. Не нанимайте людей с раздутым эго. С ними вы никогда не создадите корпоративную культуру, которая будет восхищать других.
Перестаньте работать поодиночке, работайте сообща. Не допускайте разрозненности в команде. Одиночки и разработчики-герои — признак дисфункциональности организации. Сидите рядом, вплотную. Задавайте стандарты всей командой. Работайте парами или группами; проводите review вместе. Позвольте всем участникам процесса быть ответственными за результат.
Практиковаться вместе — наиболее эффективный способ прокачать свои навыки. Взаимодействуя, мы не только вдохновляем других людей, но и учимся друг у друга. Регулярно устраивайте всей командой code retreat, coding dojo и randori. Проводите по 30 минут каждый день, просто практикуясь.
Позвольте знаниям распространяться среди людей. Учитесь вместе. Я проводил Brown Bag/Lunch&Learn сессии со всеми командами, в которых работал с 2010 года. Дважды я слышал от своих коллег: «Участие в сессиях по средам позволяет мне прокачиваться, и это очень меня мотивирует». Это наглядно отражает пользу проведения регулярных внутренних митапов.
Собирайте обратную связь и давайте ее другим. Для сбора коллективной обратной связи устройте Большую Ретроспективу. Я делаю так уже не один год. Кстати, это отличный способ погрузиться в решение проблем группой из 20 и более человек.
Учить других и делиться знаниями — это лучший способ достичь мастерства. Выступайте публично и делайте свой вклад в сообщество.
Принято считать, что разработчики ненавидят писать документацию. Но реальность говорит об обратном. Любой результат, который читают другие люди, это и есть документация. Начиная от кода системы и заканчивая кодом тестов, от сообщений к коммитам до графа коммитов в репозитории, от сообщений в логах до сообщений об ошибках — разработчики создают очень много документации, сами того не осознавая. И, что бы вы ни документировали, если люди читают это – документируйте как можно лучше.
Вы не дети. Организация — не ваши родители. Каждый должен самостоятельно управлять своей карьерой и инвестировать в себя. Если ваш вклад подразумевает трату времени или денег, сделайте это ради себя.
Как замедлиться и улучшить процесс
Каждый день мы сталкиваемся с новыми вызовами. Это не только потребности рынка и новые требования к продукту. Технические вызовы также влияют на наш прогресс.
Планы ничто, но планирование — все. Составьте план и постоянно его пересматривайте. Особенно на ранних этапах проекта, когда нужна максимальная гибкость. Ежедневной сверки с планом, например daily scrum или daily standup недостаточно. Необходимо теснее взаимодействовать внутри команды, работать парами и сверяться с планом еще чаще. Сохраняйте минимальную длину итераций вплоть до одной недели. Организуйте множество каналов обратной связи, проводя регулярные review и демо-сессии.
Определите краткосрочные и долгосрочные цели. Краткосрочные цели задают фокус для команды, долгосрочные препятствуют его потере.
Если хотите понять, почему что-то идет не так – визуализируйте поток работы, как с технической, так и с организационной точки зрения. Визуализируйте ошибки и провалы, чтобы максимизировать обучение на собственном опыте.
Никогда не принимайте решений на основе чувств. Всегда собирайте данные, анализируйте и принимайте решения на их основе. Также важно предоставить каждому разработчику доступ к продуктовым и техническим метрикам. Это повышает вовлеченность и понимание разрабатываемого продукта.
Пустые траты (waste) — это все, на что вы тратите время, но что не имеет ценности для бизнеса. Находите и устраняйте пустые траты в офисе, в коде и в бизнес-процессах.
Бойскауты оставляют стоянку более чистой, чем когда они пришли. Та же философия применима к разработке программного обеспечения. Следуйте правилу бойскаута и оставьте код более чистым после каждого внесения изменений. Если вы собираетесь добавить новый функционал и видите в файле недочеты, которые можно исправить — сделайте это, не спрашивая разрешения. Не забудьте прежде всего написать тесты. Это придаст вам уверенности при внесении изменений.
Вы можете обнаружить пустые траты в любой точке цикла разработки системы. Следуйте четко сформулированным критериям готовности (definition of done) и устраняйте задачи в духе «на 90% закончил, осталось еще 90%».
Не допускайте возникновения долгоживущих веток – они считаются злом. Не проверяйте свой код вручную. При ручном тестировании вы, скорее всего, будете проверять успешный сценарий выполнения. Все остальные сценарии могут быть проверены только при помощи кода. Поэтому отнеситесь к этому вопросу серьезно.
Как замедление может улучшить качество продукта
Одно можно сказать точно — без качественной кодовой базы вы не сможете быть гибкими, уж извините. Первое, что необходимо сделать – устранить технический долг и исправить ошибки. Если это необходимо, приостановите разработку нового функционала и сосредоточьтесь на исправлении ошибок.
Подход «быстренько исправлю, потом задеплоим» не работает в нынешних реалиях, потому что он слишком рискованный. При устранении ошибок необходим более дисциплинированный подход. Прежде всего, напишите тест, который воспроизводит проблему. После этого исправьте баг и убедитесь, что теперь тест проходит. Теперь можно спокойно отправлять исправление на production.
Я работал в командах, которые тратили почти все свое время на исправление ошибок и сопровождение проекта. Причина их страданий заключается в нестабильной работе на production. Чтобы продолжить разрабатывать новый функционал, одновременно исправляя ошибки, придется разделить команду на виртуальные команды. Например, в каждую итерацию мы выбираем двоих ребят, которые занимаются поддержкой и исправлением ошибок. Мы называем их Бэтменом и Робином. Независимо от того, какой функционал вы торопитесь закончить, баги исправляются без отрыва от основной разработки.
Нередко разработчики и так используют одну из практик замедления для дальнейшего ускорения — pull request-ы. Они останавливают текущую разработку, выполняют проверки и проводят code review, чтобы улучшить качество кода. Непроверенный код никогда не попадет на production.
Нашей конечной целью должен быть переход к Continuous Delivery и частые релизы. Начиная с использования веток git и заканчивая стратегиями развертывания, от способов обеспечения обратной связи к практикам автоматизированного тестирования – для всего этого необходим особый подход.
Практики, используемые вами на разных этапах цикла разработки ПО, наглядно показывают, как быстро вы ведете разработку. При работе с ветками используйте подход «commit early, commit often, perfect later, publish once». В случае работы без веток используйте Feature Toggles. Это позволит устранить пустые траты времени.
Я использую TDD уже не один год. Нередко люди жалуются мне, что TDD негативно влияет на скорость разработки. Joe Rainsberger поделился своими мыслями о TDD в twitter: «Переживаете, что TDD замедлит ваших программистов? Не надо. Вероятно, им и нужно замедлиться».
TDD – это больше рефакторинг, чем тестирование; больше размышления, чем кодинг; больше простота, чем элегантность. Вот почему TDD ведет к более высокому качеству. При использовании TDD у вас будет лишь минимально достаточное количество тестов и простой дизайн.
Вы когда-нибудь добивались стопроцентного покрытия кода тестами? Я достиг его в трехмесячном проекте, покрыл тестами каждую строчку production-кода. В тот момент я ощущал себя героем со сверхспособностями. Но когда мы развернули систему на preproduction для проведения приемочного тестирования, то заметили, что четыре функции не работают. Я написал интеграционные и функциональные тесты, чтобы найти и исправить ошибки. В тот момент я понял, что unit-тесты не гарантируют хороший дизайн и работающий функционал. Перестаньте считать процент покрытия кода тестами. Эта метрика ничего не показывает.
Исправляйте ошибки сразу, если для этого понадобится 30 минут или меньше. Дополнительно используйте 20% времени для устранения технического долга.
Как правило, мы пишем код без намерения менять его в дальнейшем. При проектировании системы мы аналогичным образом выбираем технологии и инструменты, планируя не менять их в будущем. Но мы ошибаемся. Рефакторинг должен быть возможен на любой стадии проекта. Как говорит Kent Beck, мы должны сделать легкие изменения, чтобы дальнейшие изменения были легкими. Чтобы это стало возможным, мы храним код всех наших микросервисов в моно-репозитории. Это позволяет сделать рефакторинг легким, и это действительно необходимо.
Любое решение при проектировании ошибочно, если оно принято раньше, чем стало необходимым. Следует ждать последнего приемлемого момента для принятия решения. Мы используем архитектуру «Порты и адаптеры», чтобы достичь слабой связаности (low coupling) и высокого зацепления (high cohesion) на уровне дизайна всей системы. Благодаря этому, мы получаем отлично спроектированные монолиты.
Монолит – это не зло, зло – это плохой дизайн. Мы всегда начинаем с разработки монолита, а благодаря архитектуре “порты и адаптеры” мы извлекаем части функциональности в микросервисы. Как сказал Martin Fowler в своей статье Monolith First: «Начинать сразу с микросервисной архитектуры рискованно, лучше начните с монолита. Разделяйте на микросервисы, только когда и если это необходимо».
Замедление для ускорения как подход к жизни
Andreas Möller поделился своими ощущениями о разработке ПО в твите: «Я не хочу писать код, который просто работает. Я хочу писать код, который будет чистым, сопровождаемым, легким для понимания и хорошо протестированным».
Чтобы достичь этого, мы должны сосредоточить внимание на трех областях: люди, процесс и продукт. Замедляя работу людей, мы стремимся повысить профессионализм и мастерство. Замедляя процесс, мы стремимся повысить гибкость и эффективность. И замедляя работу над продуктом, мы стремимся повысить уровень автоматизации и уровень качества. Когда мы сосредотачиваемся на этих трех областях, мы начинаем взращивать культуру, делающую быструю разработку возможной.
Мы должны помнить следующее:
- Работающая система не обязательно хорошо написана
- Только настоящие профессионалы могут создать хорошо проработанную систему
- Только хорошо проработанная система позволит вам выпускать новый функционал максимально быстро
Об авторе
Lemi Orhan Ergin — мастер разработки ПО, который стремится поднять уровень мастерства в своей отрасли и делиться своим опытом с сообществом. Соучредитель Craftbase и основатель Turkish Software Craftsmanship Community. Занимается разработкой ПО с 2001 года. Активно практикует и занимается наставничеством в таких областях как Scrum, экстремальное программирование, методологии разработки и web-технологии.