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

  1. Определите точку изменения
  2. Найдите точку перегиба
  3. Разорвать зависимости
  4. Напишите тесты
  5. Рефакторинг

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

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

Определите точку изменения

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

Найдите точку перегиба

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

Разорвать зависимости

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

Вот структура класса Customer (фрагменты кода написаны на Java)

Чтобы проверить нашу точку перегиба, необходимо создать экземпляры объектов Customer. Очевидно, объект Customer зависит от CustomerView, поэтому представление также должно быть создано. Это может стать еще более сложным, если CustomerView зависит от любого другого объекта. Существуют определенные методы, такие как Извлечь интерфейс и переопределить фабричный метод, которые могут облегчить создание экземпляров.

Извлечь интерфейс

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

Извлечь и переопределить фабричный метод

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

Написание тестов

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

Рефакторинг

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