Хабрахабр

[Перевод] Дзен и искусство поддержки чистого кода

Привет, Хабр!

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

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

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

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

Наводим порядок в корпоративном гараже

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

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

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

Наводим порядок в разработке ПО

Разберем конкретный пример: инкрементный рефакторинг.

Не знаю, какое именно слово ставит их в тупик: «инкрементный» или «рефакторинг». Многих это выражение озадачивает.

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

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

Постепенный рефакторинг

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

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

Правило туриста

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

Перед нами – фрагмент кода, и нам нужно добавить новое условие в список имеющихся конструкций. Именно так работает и постепенный рефакторинг. Решаем, что его нужно переоформить в виде switch или оператора выбора, одновременно добавляя условие. Замечаем, что список реализован в виде большого блока if/else. Да, вы правы: ненамного. Можно возразить: а разве это намного лучше, чем блок if/else? Когда кто-то следующий будет читать этот код после вас, он сможет еще лучше его доработать его, поскольку вы улучшили для него исходную позицию. Но чуть-чуть лучше. Просто радуйтесь, что обнаружили это сейчас, а не глубокой ночью, когда вам прилетит соответствующий тикет от службы техподдержки. Если вам доводилось делать что-то подобное ранее, то вы, вероятно, замечали, что, просто внимательно прочитав все условия, вы иногда находили то дублирующиеся конструкции, то неоптимальный порядок выражений; возможно, вам попадалось какое-нибудь условие, которое никогда не может быть выполнено, а то и логическая «дыра», через которую вся управляющая последовательность провалится через блок if/else, а некоторый случай вообще обработан не будет. В такой момент, когда глаза слипаются, нет совершенно никакого желания разбираться в путаном коде.

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

“Долгосрочный” –это обычно не так долго, как кажется

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

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

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

Что такое быстро, что такое медленно?

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

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

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

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

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

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

Технический долг как метафора

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

Те, кто так говорит, не понимают эту метафору, а возможно – и никаких метафор вообще.

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

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

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

Это обычная халтура. Срезание углов ради того, чтобы сдать работу побыстрее – это не накопление технического долга.

Кто ответственный?

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

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

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть