Oops... your message was not sent

Your message has been successfully sent

тематические истории, основанные на опыте компании JetRuby
Веб-разработка

Рефакторинг как положено. Часть 1 — планирование

Нам (и далеко не только нам) часто приходится иметь дела с проектами, которые

  1. писались очень давно;
  2. писались быстро и некачественно.

Как обеспечить стабильное продвижение такого проекта? Правильный ответ на этот вопрос состоит из одного слова: рефакторинг. Во-первых, он повышает читаемость кода, что экономит кучу времени. Во-вторых, красивый код работает более надежно. Существует масса исследований, посвященных этому вопросу. И в каждом из них с большим отрывом побеждал более красивый и структурированный код. В нем тоже могут быть ошибки. Но их будет в несколько раз меньше.

Постановка проблемы

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

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

Однако бывают случаи, когда есть смысл сначала полностью заняться рефакторингом, а уже потом быстро и уверенно двигаться дальше. Все индивидуально. Невозможно выделить набор общих правил, так как все зависит от конкретного проекта. И все же правила существуют. Прежде всего, они касаются планирования рефакторинга.

На что смотреть в первую очередь

Структура базы данных

Совсем неважно — полностью рефакторится проект или по частям — всегда существует функционал, который необходимо добавить. Соответственно, нам нужно обеспечить возможность простого и понятного добавления новой логики. И первое, на что нужно обратить внимание — это база данных. Абстрагируясь от кода и приложения вообще, смотрим позволяет ли текущая структура базы данных имплементацию нового функционала.

Здесь опять же все индивидуально. Даже если структура базы не идеальна, мы не всегда имеем возможность ее поменять. Вполне вероятно нам придется подстраиваться под ее структуру.

Вот несколько факторов, о которых нужно помнить при миграции данных клиенту:

  • Размер базы данных;
  • СУБД MySQL, PostgreSQL;
  • На какое время сайт может уйти в maintenance (при необходимости);
  • Можно ли мигрировать данные поэтапно.

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

Незначительные причины

  • Одна таблица должна быть разбита на несколько более мелких таблиц;
  • Таблицы не нормализованы;
  • Отсутствие внешних ключей;
  • Колонка таблицы называется не так как нужно;
  • Возможность применить новые фишечки СУБД, которых не было в момент ее проектирования (PostgreSQL).

Хорошие причины

  • Неверное направление логической связи — перепутаны «has_one && belongs_to many»;
  • Необходима «many_to_many» связь вместо «has_many»;
  • Негибкая структура (то есть добавление/изменение каждой новой сущности приводит к изобретению “костылей”).

Весомые причины

  • Данные в таблице перемешаны — название таблицы абсолютно не соответствует своей сущности;
  • Применение новых фишечек СУБД прекрасно справляется с решением проблемы — ведь они были придуманы именно для таких задач (PostgreSQL).

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

Определение зависимостей проекта от фичи (при рефакторинге определенного участка)

Задача предельно проста. У нас есть фича. И есть место, куда она будет добавлена. Нам нужно разбить все классы, которые используются в этом месте, на 3 типа.

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

Что тестировать?

Как правило, проекты, которые попадают под рефакторинг, не покрыты тестами. Обычно их пишут на скорую руку, чтобы быстро выйти на рынок. Как поступить, если в наших руках оказалось такое счастье? Для начала — оценить объем тестового покрытия.

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

Какой код будет изменен?

Здесь стоит выделить два случая:

  1. Код, который мы собираемся рефакторить;
  2. Код, который мы не будем рефакторить, но и не собираемся оставлять в прежнем виде.

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

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

Вывод

Итак, перед вами универсальный план рефакторинга. Он помогает ответить на вопросы:

  • что нужно поменять?
  • сколько времени это займет?
  • как лучше организовать процесс в команде?

Но все же не забывайте, что рефакторинг — крайне нетривиальная задача. А значит, возможны непредвиденные обстоятельства. Тем не менее, планирование намного важнее, чем это может показаться на первый взгляд. Исправление ошибки на этапе планирования в 10 раз дешевле исправления такой же ошибки в работающем коде. Продолжение следует!

department
Статью подготовил
Отдел веб-разработки
Профессиональная разработка сайтов и приложений на стороне сервера и клиента. Проектирование дизайна, верстка страниц и техническое обслуживание реализованных проектов.
New Articles