Это вторая часть статьи по книге Роберта Мартина «Идеальный программист». В первой части статьи мы начали изучать, чем идеальный программист отличается от не идеального. Рассмотрели ответственность, научились говорить «нет» нереальным задачам и говорить «да» так, чтобы заказчик был, уверен, что всё будет готово вовремя. Мы определились, как писать код, принимать помощь и помогать другим. Продолжим.
7. Разработка через тестирование
Про TDD говорят много всякого разного, например, вот статья на хабре. Роберт Мартин, однако, говорит, что эта методика очень хороша.
Короткий рабочий цикл. Чем короче временной интервал от написания кода до его запуска, тем производительнее получается ваша работа. Вы можете запускать код каждый час (долго), а можете каждые пару минут (отлично!). Автотесты способствуют увеличению скорости. Написал → запустил тесты.
Три закона TDD:
- Рабочий код пишется только после того, как будет написан модульный тест, который не проходит.
- Вы пишете ровно такой объем кода модульного теста, какой необходим для того, чтобы этот тест не проходил (не компилируется = не проходит).
- Вы пишете ровно такой объем рабочего кода, какой необходим для прохождения модульного теста, который в данный момент не проходит.
Преимущества:
- Вы уверены в написанном коде
- Багов становится меньше
- Вы смелее вносите изменения. Когда весь код покрыт тестами, рефакторинг делается безболезненно.
- Тесты — отличная документация. Ваши тесты — прекрасные примеры использования кода.
- Хорошая архитектура. Только хорошо изолированный и слабо связанный код поддаётся тестированию. С TDD вы уже не напишете метод, который вызывает другой метод, который вызывает другой метод, который вызывает другой метод.
8. Тренировка
Если мы не развиваемся, значит, мы деградируем. Музыканты играют гаммы, Ф.Г. Углов в своей книге «Сердце хирурга» (http://fb2bookdownload.ru/modern-prose/213-serdce-hirurga.html) рассказывает, как он всю свою жизнь (а прожил он 104 года) тренировался в наложении швов. Адвокаты тренируют речь, военные участвуют в учениях. А как быть программистам? Им тоже нужно тренироваться?
Пианист не задумывается, как ему нажимать на клавиши: он думает о музыке, т.е. его мысли находятся на более высоком уровне. Мы с вами не задумываемся, как клацать по клавиатуре: пальцы сами набирают текст, в то время как мозг работает на более высоком уровне: думает о статье или о коде. Хорошо бы, если мы не будем думать о тривиальных задачах программирования: типах данных, базовых кодовых конструкциях и паттернах, а вместо этого будем думать о бизнесе клиента. Тренируйтесь, чтобы совершенствоваться в программировании.
Ката. Вы тренируетесь реализовывать определённый алгоритм (например, быструю сортировку). Вы не решаете задачу, а тренируетесь в выполнении действий, необходимых для решения. Это помогает запомнить горячие клавиши, закрепить в подсознании пары «задача-решение».
Вадза. Это работа с напарником. Вы выбираете ката для отработки и делитесь на роли: один пишет решение, а другой модульные тесты. Затем меняетесь. Если вы взяли новую ката, которую раньше не брали, игра становится соревновательной и интересной. Напарник, который пишет тесты влияет на решение: устанавливает ограничения и критерии оценки.
Рандори. Собирается группа. На общем экране первый участник пишет тест. Следующий участник пишет прохождение теста и следующий тест. И так дальше по кругу. Такая методика помогает выяснить, как другие люди подходят к решению задач, расширяет кругозор и повышает квалификацию.
9. Приёмочное тестирование
В требованиях всегда будут неточности и изменения. Заказчик будет менять решение, а исполнитель будет менять реализацию. Исполнитель будет додумывать за заказчика и неправильно интерпретировать его слова. Я лично видел три крупных проекта, которые сдохли по этой причине. Но есть решение: введите точные и всем понятные приёмочные испытания.
У разных людей совершенно разное понимание слова «сделать». У нас на предприятии принято пользоваться вот этим, когда сделать — значит сделать и сдать. Однако, не все принимают такое определение. Я видел случаи, когда разработчик что-то закодил и решил, что сделал. Вроде, формальные требования выполнены, однако, заказчик недоволен. Это фрилансерский подход к жизни.
Проблему решит приёмочное тестирование со строгими алгоритмами. Это TDD, только на более высоком уровне. Пишете тест на любом языке (можно на русском) и согласовываете его с заказчиком. Задача должна быть покрыта приёмочными тестами на 100%. Автор книги пишет, что эти тесты должны быть понятными заказчику и автоматизированными. Лично я не знаю, как это сделать на ранней стадии: можно писать модульные тесты, но они непонятны заказчику. А можно писать тесты в Селениуме, но это уже более поздняя стадия. Если кто поделится рецептами для .NET, буду благодарен.
Что делать, если тест написан неправильно? Вы разработчик и у вас есть мозги. С их помощью вы можете увидеть ошибки в приёмочном тесте. Позиция «сделаю как написано» — это худшее, что можно придумать: вы сделаете хуже и себе и людям, поэтому единственный вариант исправления ситуации — это поговорить с разработчиком теста.
Интерфейс будет меняться. Чтобы смена интерфейса не ломала селениумовские тесты, думайте об этом во время разработки. Используйте id элементов для тестирования (ok_button, select_tour) или БЭМ-нотацию.
Непрерывная интеграция. Сделайте так, чтобы тесты запускались сами после каждого пуша в репозиторий. Если вдруг вам пришло оповещение, что тесты загорелись красным, — работа всей группы должна остановиться. Это очень важный момент, который пришёл из бережливого производства: вы увидите такую методику на заводе Toyota или Tesla. Если на контроле качества обнаруживается дефект, весь конвейер останавливается и начинается поиск проблемы. Станки перенастраиваются или чинятся и процесс запускается дальше. Цена ошибок слишком высока, чтобы их игнорировать.
10. Стратегии тестирования
Тестировщики не должны противостоять разработчикам. Хотя и кажется, что их роли антагонистичны, такое противостояние контрпродуктивно. Хорошо, когда тестировщик всеми силами помогает разработчику: ищет баги и описывает их так, чтобы разработчик максимально быстро понял, в чём дело, как воспроизвести и как починить.
Автор описывает пирамиду автоматизации тестирования
Про модульные тесты мы всё знаем, а про остальные чуть подробнее.
Компонентные тесты проверяют отдельный кусок системы. Аналитики описывают бизнес-правила как раз на уровне компонентов, и компонентные тесты становятся приёмочными тестами для бизнес-правил. Пример: тестирование системы поиска пациентов.
Интеграционные тесты проверяют взаимодействие между компонентами. Пример: «А как отработает поиск по пациентам, если модуль хранения пациентов отвалится?» или «как отработает связка модуля хранения счетов с модулем оплаты, если внешний эквайринг перестал отдавать валюту?»
Системные тесты — предельный случай интеграционных тестов. Обычно, это тесты производительности и пропускной способности. Они проверяют не поведение системы, а её конструкцию.
Исследовательские тесты не автоматизируются. Это тот случай, когда мы ходим по системе и ищем, где и что можно поломать. Ищем неожиданное поведение и подтверждаем ожидаемое.
11. Планирование
Роберт Мартин пишет о своём распорядке. Он говорит, что встаёт в 5 утра, едет на велосипеде в офис, пишет расписание рабочего дня на доске. Расписание делит на 15-минутные интервалы, оставляя каждый час по 15 минут на отвлечения. После 15:00 хаос достигает апогея и дальнейшее планирование бессмысленно: идёт разгребание накопившихся дел.
Получается, автор использует буфер, который описан в статье «Сделать завтра». Такая схема может давать сбои, но в целом, позволяет навести порядок в рабочем времени.
Встречи — зло и только иногда добро.
Когда я работал в крупнейшей транспортной компании страны, я понял, что значит много встреч. Совещания там проводятся по любому поводу и без повода. Согласование макета страницы промо-сайта — это встреча пяти человек, каждый из которых после совещания соберёт своё мини-совещание. Для того, чтобы передать какие-то данные с внешней части сайта в учётную систему, нужно не одно совещание, а пять. Это безумно выматывает и служит поводом увольнения.
Автор пишет, что в США совещание стоит 200 долларов в час на каждого участника (зарплаты, премии, помещения). А посчитал и получилось, что в России сильно дешевле: ≈13 долларов в час на каждого. Но всё равно дороговато.
Отказ от участия и уход со встречи
Вы можете отказаться от участия. Если совещание бесполезно, не несёт пользы для вашего текущего проекта, не окупится в будущем — смело отказывайтесь. Нормальный руководитель будет защищать ваше право отказа: для него ваше время столь же ценно, как и для вас.
Если же вы пришли на встречу, а она затягивается или идёт бесполезно, уточните, точно ли вы нужны, нельзя ли изменить повестку дня и обсудить важные для вашего участия вопросы сразу. Если это не помогает, выберите подходящий момент и покиньте помещение.
Повестка дня
Я не участвую во встречах без повестки дня. Это сжирает ваше время и не несёт полезного действия. Когда вас приглашают на встречу, уточните о её цели и повестке дня. Если мне говорят, что «обсудить текущие вопросы», я говорю так: «Для встречи нужна цель и повестка. Давайте уточним эти вещи и будем делать встречу, если она действительно требуется». Чаще всего повестка не образуется и такие встречи проходят без меня. Ну и слава Богу.
Пятиминутка — добро
Это часть гибкой методологии и без неё никуда. Каждый участник по очереди говорит:
1. Что я сделал вчера?
2. Что я буду делать сегодня?
3. Какие сложности мне предстоит решить?
Это быстро и не занимает много времени. Однако, есть компании, в которых пятиминутка превращается в сорокоминутку. Так делать не нужно.
12. Концентрация
Ману концентрации легко растерять, хотя она очень нужна. У нас творческая работа и без концентрации нам никуда. Есть несколько важных вещей, чтобы поддерживать концентрацию.
Нормальный ночной сон. Управляйте временем сна таким образом, чтобы нормально высыпаться и иметь максимальную производительность днём. Чересчур много тоже не нужно спать. Берите пример с великих.
Кофеин. Автор пишет, что можно поглощать умеренные дозы кофеина, но призывает быть осторожным. Я с ним не согласен и отношу кофе и чай к интоксикациям, которые лучше не употреблять. По этому поводу есть книжка «Полезная вредная привычка». Сам не читал, но вот аннотация.
Физические упражнения. Тело нуждается в упражнениях. Погоняйте кровь и лимфу, проехавшись на велосипеде или присев 20 раз прямо в кабинете. Я отмеряю время помидорками и в паузах приседаю, отжимаюсь, делаю «Сурью Намаскар».
Ввод и вывод. Чтобы из вас вышло что-то хорошее, нужно, чтобы в вас вошло что-то хорошее. Стимулировать собственное творчество помогает чужое творчество. Хорошо подходит научная фантастика.
13. Уклонение от работы
Инверсия приоритетов
Несколько раз я замечал за собой такую штуку: есть задача с первым приоритетом, однако, она мне не нравится, и я ищу любой повод, чтобы заняться чем-то ещё. Когда я был маленький, мне как-то дали задачу по актуализации тестовых сценариев уже почти сдохшей системы. Эта задача была для меня настолько неинтересной, что я находил любой повод, чтобы отвлечься. Такое поведение называется инверсией приоритетов: менее важным задачам мы присваиваем высший приоритет. Для профессионалов такое поведение не годится. Мы должны решать задачи в порядке приоритетов, а не по личным предпочтениям.
Тупик — это когда вы принимаете решение, а оно оказывается не очень хорошим и чем дальше вы углубляетесь, тем хуже. Нужно отпустить кактус. Говорят, что, если вы оказались в яме, прежде всего перестаньте копать. Наберитесь смелости и откажитесь от тупиковой ветки. Признайтесь, что вы были неправы, выслушайте альтернативные мнения и отступите. Между прочим, для отступления тоже нужна смелость.
Грязь в коде снижает производительность до нуля. Все мы хотим писать чистый совершенный код. Однако, приходит время и к нам приходит заказчик с изменившимися требованиями. Тут у вас есть два варианта: вернуться назад и изменить архитектуру или прикрутить костыль. Костыли в коде имеют привычку плодиться очень быстро. Как только вы прикрутили первый, — ждите второй, третий и двадцатый. Так рождается система, которую невозможно поддерживать и, после того, как вы уйдёте, те, кто придут на ваше место скажут: «Это полное дерьмо. Тут нужно всё переписать». Так ваш проект неминуемо идёт к провалу.
14. Оценка
Бизнес считает оценку обязательством, а разработчик — предположением. В этом есть принципиальное различие. Я надеюсь, всем понятно, чем обязательство отличается от предположения. Менеджер всегда будет добиваться от разработчика обязательства:
— Ты сделаешь переход на ESB за две недели?
— Можем, но, думаю, мне нужно три недели. Я никогда не работал с шинами.
— Тогда пишем три недели?
— Нет, может уйти и 10-11 недель, если наши партнёры не смогут быстро перестроиться на ESB.
Автор книги пишет, что для оценки можно использовать методику PERT и давать три оценки оптимистичную, номинальную и пессимистичную.
Оптимистичная оценка даётся максимально оптимистично. Это тот случай, когда всё идёт идеально и нет никаких проблем. Вероятность низкая, но её нужно учесть. Номинальная оценка — это стандартная ситуация, когда всё идёт более-менее хорошо. Есть небольшие ожидаемые трудности. Пессимистичная оценка — это когда всё идёт плохо: партнёры не понимают, что мы от них хотим, техподдержка долго отвечает, шина теряет пакеты, а документации на вашем родном арабском языке нет.
Часто, чтобы оценить вашу задачу недостаточно только вашего мнения. Хорошо, когда задачу оценит ещё кто-нибудь. Автор предлагает собрать группу экспертов и обсуждать задачу, пока не будет достигнуто согласие в её оценке. Методик голосования множество: от устного волеизъявления до распределения задач по срокам на доске.
Прочитайте оригинал книги: там даются формулы и математика, которой нет в статье.
15. Работа под давлением
Если вы работаете под давлением, — это, скорее всего, непродуктивно. Когда на вас кричат, всё время чего-то требуют, стучат кулаком об стол, краснеют, зеленеют и лишают премии, — это не самый лучший стимул к работе.
В моей работе такие ситуации не встречаются. Однако, автор пишет, что так было с ним.
Лучше всего избегать ситуаций, вызывающих давление, не принимать обязательств под давлением и не устраивать грязь в коде. Бывает так, что бизнес принимает обязательства за вас, но вы вовсе не обязаны принимать ответственность за эти обязательства: пусть она лежит на том, кто их принял.
Ещё руководитель может сказать: «Нам нужно срочно-срочно, поэтому сейчас писать тесты не нужно. Потом допишем». Не ведитесь и отстаивайте свою точку зрения. Даже в кризисных ситуациях нужно применять TDD или TLD, но ни в коем случае не отказываться от тестирования. Это обернётся большими проблемами в будущем.
16. Программисты
Оставшуюся часть книги я перескажу краткими тезисами без подробных расшифровок.
- Программисты не любят работать с людьми. Именно поэтому они и программисты: они предпочитают работать с предсказуемыми машинами, чем с непредсказуемыми людьми.
- Программист принимает правила работодателя. Если программист не принимает правил, он увольняется или его увольняют.
- Программист пишет код, который принадлежит команде. Любой другой член команды может внести изменения в ваш код и вы можете внести изменения в чужой кусок кода. Это накладывает ответственность за то, как вы пишете.
- Программисты работают парами. Если не всегда, то хотя бы иногда. Иногда очень полезно подсмотреть за тем, как кто-то работает. Программисты-одиночки вместо парного программирования смотрят скринкасты.
- Программисты работают в группах. А хорошие группы формируются не сразу. Процесс притирания может занять полгода или даже год. Лучше отдавать проект группе, чем временно формировать группу для проекта, а потом расформировывать и перераспределять.
- У программиста есть наставники. Лучше всего, если это живые люди. Но, возможно, это авторы книг, статей, блогов и видеоуроков. Почти все наши знания мы получаем по парампаре и только иногда придумываем что-то сами и при этом частенько изобретаем велосипед.
- Программисты пользуются современными инструментами. Используют систему управления исходным кодом, постановкой задач, непрерывную сборку, инструменты тестирования.
Заключение
Книга перевернула моё понимание о профессионализме и дала понимание, куда можно стремиться. Кто-то в комментах к первой части пишет, что всё это написано про сферического программиста в вакууме. Но взгляните на заголовок статьи. Там написано «идеальный», так что тут описано то, к чему нужно идти. Начните с двух-трёх пунктов и постоянно возвращайтесь к книге, вспоминая, что ещё вы можете улучшить.
Счастья вам!
Иллюстрации Александра Корнилова
← Первая часть статьи