C++:
Рефакторинг

Как это делать:

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

#include <iostream>

class Widget {
public:
    void init(bool verbose) {
        // Логика инициализации
        // ...

        // Подробное логирование
        if (verbose) {
            std::cout << "Виджет инициализирован!" << std::endl;
        }
    }
};

// Использование:
Widget w;
w.init(true);

Вывод:

Виджет инициализирован!

Рефакторинг этого для более чистых, более сфокусированных методов может выглядеть так:

#include <iostream>

class Widget {
public:
    void init() {
        // Только логика инициализации
        // ...
    }

    void logInitialization() const {
        std::cout << "Виджет инициализирован!" << std::endl;
    }
};

// Использование:
Widget w;
w.init();
w.logInitialization();

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

Углубленное изучение

Концепция рефакторинга, как мы ее знаем сегодня, зародилась в сообществах программистов на Smalltalk в 1980-х годах и была широко популяризирована книгой Мартина Фаулера “Рефакторинг: Улучшение дизайна существующего кода” от 1999 года. Сегодня рефакторинг является ключевой частью современной разработки программного обеспечения, интегрированной в различные методологии разработки, такие как Agile и TDD (Разработка через тестирование).

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

Детали реализации рефакторинга могут быть очень детализированными. Существует множество “запахов кода”, которые могут побудить к рефакторингу, такие как длинные методы, большие классы или дублированный код. Существуют автоматизированные инструменты, которые могут помочь в рефакторинге, например, “Clang-Tidy” для C++, который может обнаруживать проблемы и даже применять некоторые исправления.

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

См. также

Для более глубокого понимания рефакторинга и для просмотра большего количества примеров, вы можете обратить внимание на:

  • Классический текст Мартина Фаулера “Рефакторинг: Улучшение дизайна существующего кода” для основополагающих идей и стратегий.
  • Документацию Clang-Tidy на https://clang.llvm.org/extra/clang-tidy/ для поддержки автоматизированного рефакторинга в C++.
  • “Эффективная работа с устаревшим кодом” Майкла Фезерса, который предоставляет техники для безопасного рефакторинга в контексте неидеальных существующих кодовых баз.