О вреде рефакторинга и сокращении его необходимости (PAI)
В прошлых публикациях (техвремя, техразвитие и техдолг) мы подробно поговорили о том, что не все задачи одинаково полезны для того, чтобы тратить на них ограниченные ресурсы технического времени. Одна из самых коварных — рефакторинг. Он выглядит как инвестиция в будущее, но часто превращается в бездонную яму для ресурсов. Или скорее в казино. Разберёмся, почему так происходит и как этого избежать.
Рефакторинг (или переработка кода) – это процесс изменения внутренней структуры программы, не затрагивающий её внешнего поведения и имеющий целью облегчить понимание её работы.
Что мы узнаем из этого определения?
Рефакторинг – не переписывание
Во-первых, рефакторинг – это перепроектирование кода, а не переписывание. В чем разница? В объекте изменения. Перепроектирование означает изменение дизайна, структуры, реализации алгоритмов – без смены функциональности.
Таким образом, из определения рефакторинга, им не являются следующие мероприятия: 1. Переписывание имеющегося кода с Obj-C на Swift или c Java на Kotlin; 2. Переписывание дизайн-системы с UIKit на SwiftUI (или аналогичные изменения для андроид); 3. Радикальное изменение интерфейсов компонентов и т.д. Во всех этих случаях не меняется ни дизайн, ни структура кода, ни алгоритмы.
Сфера применения рефакторинга очень узкая — и её можно ещё дополнительно сократить.
Во-вторых, рефакторинг имеет конкретную цель — сделать код программы более легким для понимания.
Эта деталь сильно сокращает сферу применимости рефакторинга. Какой код должен быть лёгким для понимания? Тот, который часто читается, а значит и меняется. Чаще всего меняется продуктовый код. Инфраструктурный и обслуживающий код меняется редко – значит, и причин для его рефакторинга мало. Внезапно!
Отсюда вытекает не всем известное, но очень важное следствие: специальными инструментами и мероприятиями можно сократить объем кода, к которому необходимо применять рефакторинг.
Такими мероприятиями могут быть: 1. инкапсуляция и изоляция; 2. модуляризация (обсудим в одном из будущих постов); 3. Single Responsibility; 4. Open/Closed.
Ставьте смайлик собачку 🐶, если хотите, чтоб я подробнее написал о том, как сокращать необходимость в рефакторинге без негативных последствий для загнивания кодовой базы.
Необходимое условие для рефакторинга: достаточное покрытие тестами всех уровней
В-третьих, рефакторинг обязан гарантировать отсутствия изменений внешнего поведения.
Чем это можно гарантировать? Я знаю только один достаточно дешевый способ – наличие достаточного покрытия кодовой базы, подвергающейся рефакторингу, тестами различных уровней пирамиды тестирования. Это – необходимое условие начала рефакторинга.
Например, Мод Лемер, СТО Slack, в своей книге «Масштабируемый рефакторинг. Возвращаем контроль над кодом» пишет об этом так: «Поэтому бессмысленно прилагать какие-либо усилия к началу рефакторинга, пока не достигнут достаточный тестовый охват».
Вывод:
Перед тем как запланировать рефакторинг, задайте себе следующие вопросы: 1. Этот код меняется чаще раза в месяц? 2. Его сложно понять новому разработчику или джуниору? 3. У нас есть тесты, покрывающие 50+% логики? 4. Нельзя ли инкапсулировать или изолировать этот код, чтобы снизить частоту его изменений?
Рефакторинг оправдан только тогда, когда вы ответили «да» на 3 вопроса из четырех. В остальных случаях – ищите альтернативы.
И еще раз: не пытайтесь прикрывать рефакторингом обыкновенное бесполезное «переписывание» ради эстетики и красоты.
А у вас были случаи, когда рефакторинг оказался полным провалом? Пишите мне в личку или в комментарии – мне будет очень интересно!
В следующем посте я покажу вам лучшие практики по экономии усилий и повышению эффективности при миграции с одного языка разработки на другой. В частности с Objective С на Swift.
C u!
· 1 ч
Рефакторинг так же уместен при быстром развитии продукта, когда тестируются гипотезы. Сначала реализуем на коленке, чтобы быстро проверить и если гипотеза подтвердилась, рефакторим. Иначе удалили модуль и забыли.
Остальное все по делу 🙏 классный пост, спасибо!
ответить
коммент удалён
· 1 ч
Есть другое мнение. MVP ВСЕГДА выбрасываются. Гипотезы проверяются быстро, "на коленке", как Вы говорите, но далее даже в случае успеха код выбрасывается полностью. Это мнение основано на тезисе о том, что отрефакторить "наколеночное" будет стоить сильно дороже, чем реализовать с нуля хорошо продуманную реализацию. Запуск полноценного проекта с нуля будет эффективнее.
К сожалению, забыл, чья это мысль, чтоб указать ссылку. Думаю, читатели мне подскажут.
Спасибо за еще один крайне дельный комментарий! 🤝
ответить
ответ удалён
· 1 ч
Спорно, мы mvp ни разу не выбрасывали, обычно допиливали и иногда рефакторили.
Кстати, вопрос - что вы делаете, если заканчивается поддержка текущей версии фреймворка, а новая версия кардинально отличается? Рефакторите или выбрасываете и пишите с нуля?
ответить
ответ удалён
· 53 мин
Ну, мой изначальный пост, в комментах к которому мы разговариваем, для 80% разработчиков не просто “спорный”, он еретический! И за такое глупых менеджеров сжигать нужно по мнению этих самых разработчиков. А вот для Вас этот пост – “… всё по делу”.
С выкидыванием MVP примерно так же. Поищу, чья мысль, как её обосновывают и напишу подробный постик. Самому интересно стало. Тут у меня пробел, а я, как-никак, провожу ретроспективу, а значит, обязан закрыть если не все, то большую часть белых пятен!
По поддержке версий. У нас все крайне просто. За нас все решил Великий и Ужасный Регулятор: все версии с той даты, что нельзя называть, просто запрещены 😁
С другой стороны: 1. У нас не так много сторонних зависимостей именно благодаря ДИБ, которому мы в этом вопросе благодарны. 2. Выше в посте я отмечал, что рефакторинг уместен только в ограниченных случаях: как минимум он должен что-то привнести. А еще было б неплохо, чтоб это привнесенное не просто окупило затраты на привнесение, но и зарабатывать начало. А с этим, будем честны, у 80% фреймворков – большие проблемы. Они не ценность добавляют, а “красоту кода разводят”. Фреймворки – это ж прижизненные памятники начинающим разработчикам, нет? Ладно, не все из них. Есть единицы действительно стоящих, у которых еще и стоящие изменения переодически выходят.
ответить
ответ удалён