Меню
Главная
Случайная статья
Настройки
|
Перепроектирование кода (англ. refactoring), или рефакторинг, реорганизация кода, равносильные преобразования алгоритмов — процесс изменения внутренней структуры программы, не затрагивающий её внешнего поведения и имеющий целью облегчить понимание её работы[1][2]. В основе перепроектирования кода лежит последовательность небольших равносильных (то есть сохраняющих поведение, эквивалентных) преобразований. Поскольку каждое преобразование незначительное, программисту легче проследить за его правильностью, и в то же время вся последовательность равносильных преобразований может привести к существенной перестройке программы и улучшению её согласованности и чёткости.
Содержание
Цели перепроектирования кода
Цель перепроектирования кода — сделать код программы более легким для понимания; без этого перепроектирование кода нельзя считать успешным.
Перепроектированик кода следует отличать от оптимизации производительности. Как и перепроектирование, оптимизация обычно не изменяет поведение программы, а только ускоряет её работу. Но оптимизация часто затрудняет понимание кода, что противоположно целям перепроектирования кода[3].
С другой стороны, нужно отличать перепроектирование кода от реинжиниринга, который осуществляется для расширения функциональности программного обеспечения. Как правило, крупное перепроектирование кода предваряет реинжиниринг.
Причины применения перепроектирования кода
Перепроектированик кода нужно применять постоянно при разработке кода. Основными стимулами его проведения являются следующие задачи:
- необходимо добавить новую функцию, которая недостаточно укладывается в принятое архитектурное решение;
- необходимо исправить ошибку, причины возникновения которой сразу не ясны;
- преодоление трудностей в командной разработке, которые обусловлены сложной логикой программы.
Признаки плохого кода
Во многом при рефакторинге лучше полагаться на интуицию, основанную на опыте. Тем не менее имеются некоторые видимые проблемы в коде (англ. code smells), требующие выполнения перепроектирования кода:
- дублирование кода;
- длинный метод;
- большой класс;
- длинный список параметров;
- «жадные» функции — это метод, который чрезмерно обращается к данным другого объекта;
- избыточные временные переменные;
- классы данных;
- несгруппированные данные.
Перепроектирование кода
В программировании термин перепроектирование кода означает изменение исходного кода программы без изменения его внешнего поведения. В экстремальном программировании и других гибких методологиях перепроектированик кода является неотъемлемой частью цикла разработки ПО: разработчики попеременно то создают новые тесты и функциональность, то выполняют перепроектирование кода для улучшения его логичности и прозрачности. Автоматическое юнит-тестирование позволяет убедиться, что перепроектирование кода не разрушило существующую функциональность.
Иногда под перепроектированием кода неправильно подразумевают коррекцию кода с заранее оговоренными правилами отступа, перевода строк, внесения комментариев и прочими визуально значимыми изменениями, которые никак не отражаются на процессе компиляции, с целью обеспечения лучшей читаемости кода (см. Форматирование кода[англ.]).
Перепроектированик кода изначально не предназначен для исправления ошибок и добавления новой функциональности, он вообще не меняет поведение программного обеспечения[3] и это помогает избежать ошибок и облегчить добавление функциональности. Он выполняется для улучшения понятности кода или изменения его структуры, для удаления «мёртвого кода» — всё это для того, чтобы в будущем код было легче поддерживать и развивать. В частности, добавление в программу нового поведения может оказаться сложным с существующей структурой — в этом случае разработчик может выполнить необходимое перепроектированик кода, а уже затем добавить новую функциональность.
Это может быть перемещение поля из одного класса в другой, вынесение фрагмента кода из метода и превращение его в самостоятельный метод или даже перемещение кода по иерархии классов. Каждый отдельный шаг может показаться элементарным, но совокупный эффект таких малых изменений в состоянии радикально улучшить проект или даже предотвратить распад плохо спроектированной программы.
Методы перепроектирования кода
Наиболее употребимые[4] методы перепроектирования кода:
- Изменение сигнатуры метода (Change Method Signature)
- Инкапсуляция поля (Encapsulate Field)
- Выделение класса (Extract Class)
- Выделение интерфейса (Extract Interface)
- Выделение локальной переменной (Extract Local Variable)
- Выделение метода (Extract Method)
- Генерализация типа (Generalize Type)
- Встраивание (Inline)
- Введение фабрики (Introduce Factory)
- Введение параметра (Introduce Parameter)
- Подъём метода (Pull Up Method)
- Спуск метода (Push Down Method)
- Переименование метода (Rename Method)
- Перемещение метода (Move Method)
- Замена условного оператора полиморфизмом (Replace Conditional with Polymorphism)
- Замена наследования делегированием (Replace Inheritance with Delegation)
- Замена кода типа подклассами (Replace Type Code with Subclasses)
Изменение сигнатуры метода (Change Method Signature)
Суть изменения сигнатуры метода заключается в добавлении, изменении или удалении параметра метода. Изменив сигнатуру метода, необходимо скорректировать обращения к нему в коде всех клиентов. Это изменение может затронуть внешний интерфейс программы, кроме того, не всегда разработчику, изменяющему интерфейс, доступны все клиенты этого интерфейса, поэтому может потребоваться та или иная форма регистрации изменений интерфейса для последующей передачи их вместе с новой версией программы.
Инкапсуляция поля (Encapsulate field)
В случае, если у класса имеется открытое поле, необходимо сделать его закрытым и обеспечить методы доступа. После «Инкапсуляции поля» часто применяется «Перемещение метода».
Выделение метода (Extract Method)
Выделение метода заключается в выделении из длинного и/или требующего комментариев кода отдельных фрагментов и преобразовании их в отдельные методы, с подстановкой подходящих вызовов в местах использования. В этом случае действует правило: если фрагмент кода требует комментария о том, что он делает, то он должен быть выделен в отдельный метод. Также правило: один метод не должен занимать более чем один экран (25-50 строк, в зависимости от условий редактирования), в противном случае некоторые его фрагменты имеют самостоятельную ценность и подлежат выделению. Из анализа связей выделяемого фрагмента с окружающим контекстом делается вывод о перечне параметров нового метода и его локальных переменных.
Перемещение метода (Move Method)
Перемещение метода применяется по отношению к методу, который чаще обращается к другому классу, чем к тому, в котором сам располагается.
Замена условного оператора полиморфизмом (Replace Conditional with Polymorphism)
Условный оператор с несколькими ветвями заменяется вызовом полиморфного метода некоторого базового класса, имеющего подклассы для каждой ветви исходного оператора. Выбор ветви осуществляется неявно, в зависимости от того, экземпляру какого из подклассов оказался адресован вызов.
Основные принципы:
- вначале следует создать базовый класс и нужное число подклассов;
- в некоторых случаях следует провести оптимизацию условного оператора путём «Выделения метода»;
- возможно использование «Перемещения метода», чтобы поместить условный оператор в вершину иерархии наследования;
- выбрав один из подклассов, нужно конкретизировать в нём полиморфный метод базового класса и переместить в него тело соответствующей ветви условного оператора;
- повторить предыдущее действие для каждой ветви условного оператора;
- заменить весь условный оператор вызовом полиморфного метода базового класса.
Проблемы, возникающие при выполнении перепроектирования кода- проблемы, связанные с базами данных;
- проблемы изменения интерфейсов;
- трудности при изменении дизайна.
Средства автоматизации перепроектирования кода
Технические критерии для инструментов перепроектирования кода:
- базы данных программы;
- деревья синтаксического разбора;
- точность.
Практические критерии для инструментов перепроектирования кода:
- скорость;
- отмена модификаций;
- интеграция с другими инструментами.
См. также
Примечания
- М. Фаулер (2000), стр. 61-62
- Кериевски, 2008, Введение.
- 1 2 М. Фаулер (2000), стр. 62
- Кериевски, 2008.
Литература- Фаулер М., Бек К., Брант Д., Робертс Д., Апдайк У. Рефакторинг: улучшение существующего кода = Refactoring: Improving the Design of Existing Code (2000). — СПб.: Символ-Плюс, 2009. — 432 с. — 3000 экз. — ISBN 5-93286-045-6.
Ссылки
|
|