Как переписать старый код


1 2

У меня примерно год назад была задача – переписать бизнес логику, которую написал другой программист за пару лет до меня, но у проекта вообще не было тестов и логика кода была на столько сложной с различными edge cases. Даже не знаю как перевести edge cases, но это когда есть какие-то редкие случаи, которые не должны случаться, но они могут выбиваться из общей логики. 

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

Когда что-то пишешь с нуля, то ты как первопроходец учишься и создаёшь легаси для других. Когда ты переписываешь, то если стразу не учесть чего-то, допустить ошибку или изменить бизнес логику, то возникает много крику из ничего, потому что бизнес не очень любит перемены. 

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

Я не люблю кардинальных изменений и не люблю торопиться и ломать что-то, чтобы перестраивать. Для меня более интересным, а точнее более надежным является постепенный подход. 

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

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

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

Итак, я переписал код на новую логику и приступил ко второму этапу переходу на новый код одновременная работа двух версий:

 

var legacyValue = calculateValue();

var newValue = calculateValueV2();

If (legacyValue != newValue) {

 throw new Exception(“печалька”);

}

 

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

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

За три месяца одновременной работы двух версий в тестовом окружении мне удалось выявить несколько случаев, которые я упустил в тестах и они выбивались из общей логики. Этот как раз те Edge Cases, которые бизнес и программист реализовали особым способом и их теперь придётся обслуживать именно таким же способом. 

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

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


Понравилось? Кликни Лайк, чтобы я знал, какой контент более интересен читателям. Заметку уже лайкнули 2 человек


Комментарии

SergeyR

24 Сентября 2020

Очень интересный подход с одновременным выполнением старой и новой версии, теперь буду его иметь его ввиду, спасибо.


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

Еще что-нибудь

Хотите найти еще что-то интересное почитать? Можно попробовать отфильтровать заметки на блоге по категориям.

О блоге

Программист, автор нескольких книг серии глазами хакера и просто блогер. Интересуюсь безопасностью, хотя хакером себя не считаю

Обратная связь

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

Пишите мне