- •Лабораторная работа №6 Рефакторинг программного кода
- •Ход выполнения работы
- •Длинный Метод
- •Большой класс
- •Длинный список параметров
- •Расходящееся изменение
- •Хирургия дробовиком
- •Зависть по функции
- •Группы данных
- •Одержимость примитивами
- •Оператор Switch (Case)
- •Параллельные иерархии наследования
- •Ленивый класс
- •Спекулятивное обобщение
- •Временное поле
- •Цепочка сообщений
- •Посредник
- •Неоправданная близость
- •Альтернативные классы с разными интерфейсами
- •Неполный библиотечный класс
- •Класс для данных
- •Отвергнутое наследство
- •Комментарии
- •Классификация шаблонов рефакторинга
- •Примеры шаблонов рефакторинга
Неоправданная близость
Иногда классы становятся слишком близки и проводят слишком много времени с приватными частями друг друга.
Используйте Move Method и Move Field для разделения частей и уменьшения близости. Посмотрите, нельзя ли организовать Change Bidirectional Association to Unidirectional. Если у классов действительно есть общий интерес, используйте Extract Class, чтобы положить общие части в одно место.
Наследование часто ведет к неоправданной близости. Потомки всегда знают о предках больше, чем хотелось бы предкам. Используйте Replace Inheritance with Delegation, когда пора покидать дом.
Альтернативные классы с разными интерфейсами
Применяйте Rename Method к любым методам, которые делают одно и то же, но имеют разную сигнатуру. Если этого недостаточно, используйте Move Method пока интерфейсы не станут одинаковыми.
Неполный библиотечный класс
Зачастую библиотечный класс не совсем нас устраивает, но мы не можем применить что-то типа Move Method к нему. Если вам надо добавить пару методов, используйте Introduce Foreign Method. Если добавлять надо много, вам понадобится Introduce Local Extension.
Класс для данных
Бывают классы, которые содержат только поля и методы для доступа к ним. Это просто тупые контейнеры для данных и скорее всего, другие классы слишком детально ими манипулируют. Во-первых, примените Encapsulate Field и Encapsulate Collection, пока никто не видел. Посмотрите, где данные класса используются. Попробуйте применить Move Method, чтобы перенести этот код в сам класс данных. Классы для данных как дети. Они нужны на начальных этапах. Но чтобы вести себя как взрослый объект, они должны брать на себя ответственность.
Отвергнутое наследство
Подклассы наследуют методы и данные от их предков. Но иногда они не пользуются тем, что им дают.
Традиционный ответ - иерархия плохая. Вам нужно создать новый порожденный класс и применить Push Down Method и Push Down Field. Но по нашему саркастическому использованию слова традиционный, вы догадались, что мы не будем это всегда советовать. Мы используем наследование для повторного использования. Оно сопровождается плохим запахом, но обычно он не очень силен. Если отвергнутое наследство представляет собой проблему, то воспользуйтесь традиционным советом.
Комментарии
Удивительно, как часто смотришь на хорошо комментированный код и видишь, что комментарии написаны потому, что код плохой. Комментарии не причина, а индикатор плохого кода. При хорошей организации кода комментарии, зачастую, излишни.
Классификация шаблонов рефакторинга
Большой рефакторинг
Преобразование процедурного кода в объектный Convert Procedural Design to Objects
Выделение иерархии Extract Hierarchy
Рефакторинг
Композиционные:
Извлечения Extract method, Extract class
Встраивания Inline method, Inline class
Перемещения:
Перемещение Move method, Move field
Организационные:
Замена данных классом Replace Data Value with Object, Replace Array with Object
Замена структуры классом Replace Record with Data Class
Замена типа классом Replace Type Code with Class
Инкапсулирование поля Encapsulate Field
Инкапсулирование коллекции Encapsulate Collection
Замена магических чисел Replace Magic Number with Symbolic Constant
Упрощающие логические условия:
Декомпозиция условия Decompose Conditional
Объединение условий Consolidate Conditional Expression
Объединение повторяющихся условий Consolidate Duplicate Conditional Fragments
Замена условия с использованием полиморфизмом Replace Conditional with Polymorphism
Упрощающие вызовы методов:
Переименовать метод Rename Method
Добавить параметр Add Parameter
Удалить параметр Remove Parameter
Передать объект Preserve Whole Object
Замена параметра методом Replace Parameter with Method
Сокрытие метода Hide Method
Обобщения:
Выталкивания поля, метода вверх по иерархии Pull Up Field, Pull Up Method
Выталкивания поля, метода вниз по иерархии Push Down Field, Push Down Method
Выделение суперкласса Extract Superclass
Выделение интерфейса Extract Interface
Сворачивание иерархии Collapse Hierarchy