Что делать, если в наследство достался некачественный код — отвечают эксперты

Программирование — это не только написание кода, но и его исправление. Наш подписчик явно столкнулся с ситуацией, где ему потребовался совет опытного человека:

«Что делать, если в наследство достался некачественный код?»

За разъяснениями мы обратились к нашим экспертам, а полученные ответы предоставляем вашему вниманию.

Николай Лопин

Николай Лопин, преподаватель курса профессия frontend-разработчик университета онлайн-профессий Нетология

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

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

Если после недели чтения кода и документации все ещё ничего непонятно, то, кажется, код действительно «не очень». В этот момент нужно понять, как вы будете взаимодействовать с этим кодом. Вам его дали на поддержку? Или нужно его развивать?

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

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

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

Иван Шмаков

Иван Шмаков, Senior VoIP Software Developer

Для начала нужно убедиться, что код действительно плох: не исключено, что он сложен для понимания из-за специфики предметной области. Например, код DSP-контроллера чрезвычайно сложно читать без релевантного опыта. Для верности стоит посоветоваться с коллегами, более осведомленными в данном вопросе.

Если код действительно плохого качества, важно понять, можно ли закрыть на него глаза. Толерантность к чужому коду — важный скилл. Если нельзя, стоит определить:
— Какова трудоемкость переписывания кода (оценка трудоемкости — это сложно, есть риск просчитаться на целые месяцы);
— Хорошо ли ты понимаешь код, который планируешь переписать;
— А сможешь ли ты написать более качественный код;
— Если проблемный код не покрыт тестами (а так, скорее всего, и будет), то есть риск, что новый код создаст регрессию в проекте. Готов ли ты взять на себя ответственность за результат?

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

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

Александр Кравцов

Александр Кравцов, старший разработчик ПО SibEDGE

В первую очередь нужно разделить понятия наследия и некачественного кода. Legacy code — устойчивое выражение, обозначающее, что код, попавший в руки, был написан достаточно давно. И тут нужно учесть, что, возможно то, что было написано 10 лет назад очень актуально для своего времени. Назвать такой код некачественным — вряд ли, устаревшим — вполне. Это может быть вполне поддерживаемая, масштабируемая система, просто сейчас никто таких не делает. С таким кодом можно продолжить работу в определенной парадигме.

А некачественный код мог быть написан буквально вчера. И это уже совсем другой — более тяжелый случай. Если в случае Legacy code возможна дальнейшая поддержка и надстройка, то когда тебе достается откровенно плохая работа, есть смысл задуматься о рентабельности проекта в целом. В этом случае придется, скорее всего, переписывать с нуля. И тут очень важно понять, на каком этапе находится проект: если это старт, то переписать код достаточно легко, если уже заключительный этап — то проще доделать как есть, хотя риск, что в итоге система не будет работать велик. Важно объяснить это заказчику.

Анна Ухова

Анна Ухова, инженер-разработчик Роспартнер

Наверно, каждый разработчик на своем программистском поприще рано или поздно сталкивался с ситуацией, когда смотришь на чужой код и думаешь: «Это что, шутка?»

Что же делать, когда открываешь код и на глаза, кроме слез, ничего не попадает? Как не впасть в панику и не положить заявление на стол?

Понятие «некачественный код» у каждого свое. Более того, в каждом языке программирования свои парадигмы и представления об идеальном коде. Для себя я вывела несколько уровней «греха» под названием «некачественный код».

0-ой уровень:
проблема с переменными. Это очень абстрактное понятие, но если обобщить, то сюда попадает интуитивно непонятное наименование переменной (ar1, ar2, item), лишние переменные, которые нигде не используются, подтягивание одних и тех же данных несколько раз и т.д. Решить данную проблему достаточно просто, хоть и не доставит особого удовольствия. Переименовать переменные в интуитивно понятный вид (array_for_organization, obuv_items, users_telephones), удалить лишние вызовы, присваивания и переменные.

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

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

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

4-ый уровень:
самый серьезный. «Грех» четвертого уровня обычно совершают новички, не особенно знакомые с продуктом, с которым работают. Правка файлов, которые не следует править. Поясню на примере CMS для веб-разработки, т.к. я занимаюсь именно веб-разработкой. Каждая CMS основана на неком ядре, на основе которого разработчик создает нечто свое, но использует те методы, модули и классы, которые изначально заложены ядром. Так вот самый большой грех это правка файлов этого ядра. Этот «грех» очень сложно выявить, практически невозможно устранить и в процессе может доставить очень много неприятных моментов.

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

Всем хорошего дня и побольше качественного кода!

Андрей Черабаев

Андрей Черабаев, разработчик в Mediasoft

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

1. На то, чтобы разобраться с кодом, уйдет неоправданно много времени. Простой пример: команде достался по наследству функционал, работающий на четырех переменных и особой математической магии. Нужно было поменять в нем одно условие. При хорошем коде эта работа заняла бы 30 минут, но программист убил 10 часов, потому что ему пришлось практически побуквенно разбираться, как все это работает.

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

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

В общем, если при изучении legacy-кода у вас появляется стойкое ощущение, что его писала бешеная обезьяна под бутиратом, не молчите — обсуждайте возможность рефакторинга. Не получилось этого добиться — улучшайте код по мере сил в процессе. Оставлять как есть — самый неразумный вариант.

Напоминаем, что вы можете задать свой вопрос экспертам, а мы соберём на него ответы, если он окажется интересным. Вопросы, которые уже задавались, можно найти в списке выпусков рубрики. Если вы хотите присоединиться к числу экспертов и прислать ответ от вашей компании или лично от вас, то пишите на experts@tproger.ru, мы расскажем, как это сделать.

Подобрали два теста для вас:
— А здесь можно применить блокчейн?
Серверы для котиков: выберите лучшее решение для проекта и проверьте себя.