Что такое системный рефакторинг?

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

Вы уже читали книгу Эриха Мария Ремарка «Три товарища»? Если да, то вам наверняка запомнился Карл. Для тех, кто не читал: нет, Карл – это не один из трёх товарищей. Это старый потасканный автомобиль, который Отто Кёстер приобрёл на аукционе, и стоил он «не больше одного бутерброда». Знакомые Отто потешались над ним и советовали сделать из него швейную машину, но тот перебрал старый драндулет в своей мастерской, поставил в него гоночный мотор, и машина превратилась в находку. Несмотря на изношенный внешний вид, Карл теперь мог разгоняться до 190 км/час! Товарищи часто пользовались этой особенностью Карла: участвовали в соревнованиях, где на старенький автомобиль никто не ставил, ведь никто не мог догадаться, что у него под капотом.

Нет, уважаемые читатели, речь в этой статье пойдет не о литературе, а по-прежнему о системном анализе, а именно о таком явлении, как рефакторинг. Карл из «Трёх товарищей» тоже подвергся своего рода рефакторингу, правда, во времена Ремарка такого термина ещё не существовало.

Что такое рефакторинг и каким он бывает?

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

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

В целом, разница этих видов – в области применения:

  • Рефакторинг на системном уровне подразумевает изменения в логике работы приложения: переход на другие алгоритмы обработки информации и источники данных, изменение структуры данных в базе, изменения механизмов сохранения, получения и передачи данных внутри одной системы;
  • Архитектурный рефакторинг охватывает взаимодействие нескольких систем: он может включать в себя изменение механизмов интеграции, замену некоторых системных компонентов, изменение работы сервисов без изменения их контрактов, переход на новую архитектуру.
  • Рефакторинг технической документации означает периодическую вычитку технических заданий и спецификаций, улучшение структуры документов (перенос и группировка разделов, работа над логическими переходами), удаление дублирующей информации, работа над формулировками. Цель такая же, как в рефакторинге кода – повышение ясности и читаемости текста. Описание должно быть логичным и последовательным, при прочтении документа не должна возникать необходимость постоянно «перескакивать» в другие разделы за дополнительной информацией.

Примеры

Один из примеров рефакторинга на системном уровне – рефакторинг баз данных. Скорее всего вы уже слышали термин «код с душком», который ввел М. Фаулер для обозначения низкокачественного кода. По аналогии можно выделить недостатки в базе данных:

Столбцы, используемые не по назначению (многоцелевые столбцы)

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

Таблицы, в которых хранятся более одной сущности (многоцелевые таблицы)

Часто в базах используются универсальные таблицы, в которых хранятся сущности с разным атрибутным составом. Например, в таблице «clients» могут храниться данные по физическим и юридическим лицам. В такой таблице имеется множество незаполненных ячеек (КПП для физических лиц, СНИЛС для юридических лиц и т.д.).

Таблицы с большим количеством столбцов

Наличие слишком большого количество столбцов также может говорить о необходимости рефакторинга БД: скорее всего, в такой таблице хранятся атрибуты более, чем одной сущности.

Таблицы с неатомарными значениями

Некоторые значения могут храниться в БД в виде строк, хотя при их обработке всегда происходит парсинг, и ее составляющие обрабатываются отдельно. Яркий пример – хранение адресов в виде строки.

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

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

Как избежать рефакторинга?

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

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

Рефакторинг в твоей команде

  1. Фиксируйте «временные решения» и составляйте к каждому из них проработанное TO-BE решение;
  2. Обозначьте сроки, когда вы вернетесь к вопросу перехода на целевое решение и внесите обсуждение этих вопросов в план спринта;
  3. Обозначьте риски в случае неперехода на целевое решение (как правило, долгосрочные риски);
  4. Информируйте смежные команды и прочих стейкхолдеров о том, что планируется реализация временного решения и сообщайте, когда планируется переход на целевой вариант;
  5. Выделяйте время в спринте на работу с техническим долгом;
  6. Проводите оценку временной функциональности и пересматривайте при необходимости целевые варианты. Зачастую временные решения оказываются вполне рабочими;
  7. Не занимайтесь рефакторингом в ущерб проектной работе: не допускайте смещения сроков проекта или вреда работающим системам и сервисам.

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

  • При реализации новой функциональности вы не сталкиваетесь с необходимостью изобретать сложные логические конструкции;
  • Обмен данными в системе проходит быстро и без ненужных преобразований;
  • У вас не встает вопросов о полной замене какого-либо компонента или системы в виду их неуправляемости;
  • В команде не тратится слишком много времени на технические груминги и проработку дизайна;
  • Вхождение в проект новых сотрудников (аналитиков, разработчиков, тестировщиков) проходит легко благодаря понятному коду и качественной документации;
  • Ваш проект идет «в ногу со временем»: в него относительно безболезненно внедряются новые современные технологии;
  • Вы никогда не слышали о legacy-системах и сейчас пошли гуглить этот термин😊

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

Валерия Новицкая

Магистр бизнес-информатики Высшей школы экономики (направление моделирования и оптимизации бизнес-процессов). Ведущий системный аналитик, эксперт по системным интеграциям.