- •Централизованные системы контроля версий.
- •Основные команды.
- •Конфликты.
- •Просмотр различий.
- •Ответвления и метки.
- •Распределенные системы контроля версий (git, Mercurial, Bazaar).
- •Обычный workflow при работе с локальным репозитарием.
- •Общественные репозитарии.
- •Выделение метода.
- •Встраивание метода
- •Встраивание временной переменной
- •Замена временной переменной вызовом метода
- •Введение поясняющей переменной
- •Расщепление временной переменной
- •Удаление присваиваний параметрам
- •Замена метода объектом методов
- •Замещение алгоритма
- •Перемещение метода.
- •Удаление посредника.
- •Введение внешнего метода.
- •Консолидация дублирующихся условных фрагментов.
- •Удаление управляющего флага.
- •Замена вложенных условных операторов граничным оператором
- •Замена условного оператора полиморфизмом
- •Введение объекта null
- •Введение assert
- •Анти-паттерны в программировании
- •Анти-паттерны в объектно-ориентированном программировании
- •Анти-паттерны в разработке по
- •Методологические анти-паттерны
Замена метода объектом методов
Описание: Есть длинный метод, локальные переменные к-ого используются т.о., что Выделение метода произвести невозможно.
Действие: преобразовать метод в объект отдельного класса так, чтобы локальные переменные стали свойствами этого объекта. После этого можно разложить данный метод на несколько методов того же объекта.
Замещение алгоритма
Описание: Есть код со старым алгоритмом и код с новым, более понятным.
Действие: заменить тело метода новым алгоритмом.
ПЕРЕМЕЩЕНИЕ ФУНКЦИЙ МЕЖДУ ОБЪЕКТАМИ.
Перемещение метода.
Описание: Метод чаще использует функции другого класса (или используется ими), а не того, в к-ом он определен, - в данное время или, возможно, в будущем.
Действие: Создать новый метод с аналогичным телом в том классе, в к-ом он чаще используется. Тело старого метода заменить делегированием или удалить вообще.
Особенности:
Если нек.ф-ия используется только тем методом, к-ый перемещается, то ее тоже лучше переместить. Следить за тем, чтобы в подклассах или род.классе не было этого метода (реализован полиморфизм). Для адаптации метода к новому окружению необходимо определить способ ссылки на исходный класс (либо сделать поле с указателем, либо передавать как параметр ссылку на исходный объект). Исходный метод сделать делегирующим или удалить.
Перемещение поля.
Описание: Поле используется другим классом чаще чем тем, в к-ом оно определено.
Действие: Создать в целевом классе новое поле и отредактировать всех его пользователей.
Выделение класса.
Описание: Нек.класс выполняет работу, к-ую следует разделить между 2 классами.
Действие: Создать новый класс и поместить соотв.поля и методы из старого класса в новый.
class AnimatedBitmap {…}; class BitmapFile { … };
Встраивание класса.
Описание: Нек.класс выполняет слишком мало функций.
Действие: Переместить все функции в др.класс и удалить исходный.
Сокрытие делегирования.
Описание: Объект-Клиент обращается к делегируемому классу объекта.
Действие: создать на объекте-сервере методы, скрывающие делегирование.
Class Person { Department _dep; … };
Class Department { Person* _manager; … };
Person john; …
Person* manager = john.GetDepartment().GetManager();
-----------------------------------------------
Person* manager = john.GetManager();
public Person GetManager() {
return _dep.GetManager();
}
Удаление посредника.
Описание: В классе слишком много простого делегирования.
Действие: заставить клиента обращаться к делегату непосредственно.
Обратно сокрытию делегирования.
Введение внешнего метода.
Описание: необходимо ввести в класс-сервер доп.метод, но отсутствует возможность его модификации.
Действие: создать в классе-клиенте метод, в котором в качестве первого аргумента передается класс-сервер.
Особенности: создаваемый внешний метод (в клиенте) не должен обращаться к хар-кам клиентского класса (если это нужно, то передавать их в кач-ве параметра). В комментарии к методу отметить, что это внешний метод. Благодаря чему можно будет затем найти все внешние методы и поместить их в сервер.
// Foreign Method : resizin’
void ResizeBitmap( Bitmap* bmp, int ScaleX, int ScaleY ) { … }
Введение локального расширения.
Описание: Класс-сервер требуется дополнить несколькими методами, но отсутствует возможность модификации.
Действие: создать новый класс с необходимыми доп.методами и сделать его подклассом (наследование) или оболочкой (агрегирование) для исходного класса.
Особенности: применить паттерны, например, адаптер.
РЕОРГАНИЗАЦИЯ ДАННЫХ.
Самоинкапсуляция поля.
Описание: Обращение к полю осуществляется непосредственно.
Действие: Обращаться к полю только через методы доступа (в этом же классе).
Польза – только в классе или в подклассе реализована нестандартная логика доступа.
Замена значения данных объектом.
Описание: Есть нек.элемент данных, для к-ого требуется доп.данные или поведение.
Действие: Преобразовать элемент данных в объект.
Замена значения ссылкой и наоборот.
Описание: Есть много одинаковых объектов одного класса, которые нужно заменить одним объектом.
Действие: Преобразовать объект в объект ссылки.
Замена массива объектом.
Описание: Есть массивы, нек.элементы котрого означают разные сущности.
Действие: Заменить массив объектом, в к-ом есть поле для каждого элемента.
string attr[3];
attr[0] = “jpg”;
attr[1] = “320”;
attr[2] = “200”;
----------------------
ImageAttributes attr;
attr.SetExt( “jpg” ); attr.SetWidth( 320 ); …
Дублирование видимых данных.
Описание: Есть данные объекта представления (GUI), к которым нужен доступ из методов объекта предметной области.
Действие: Скопировать данные в объект предметной области. Создать объект-наблюдатель, к-ый будет обеспечивать синхронность данных.
Замена 1-направленной связи 2-направленной и наоборот.
Описание: Есть 2 класса с обратными указателями.
Действие: Добавить / убрать обратные указатели.
Замена магического числа символической константой.
Описание: Есть число, имеющее определенный смысл.
Действие: Создать константу со значащим именем и использовать ее вместо числа.
Инкапсуляция поля.
Описание: Имеется открытое поле.
Действие: Сделать его закрытым и обеспечить методы доступа.
Инкапсуляция коллекции.
Описание: Метод возвращает коллекцию.
Действие: создать методы чтения, добавления и удаления элементов.
Замена простого типа или записи классом.
Замена простого типа подклассами или состоянием/стратегией.
Замена подкласса полями.
УПРОЩЕНИЕ ВЫЗОВОВ МЕТОДОВ.
Переименование метода.
Описание: Имя метода не раскрывает его назначения.
Действие: Переименовать метод.
Добавление параметра.
Описание: Метод нуждается в доп.инф-ии от вызывающего.
Действие: Добавить соотв.параметр.
Особенности: не всегда полезно (длинный список параметров затрудняет читабельность). Если инф-ия может быть получена другим способом (через другие объекты), это предпочтительнее.
Удаление параметра.
Описание: Параметр более не используется в теле метода.
Действие: Удалить соотв.параметр.
Особенность: осторожность нужно проявлять, если метод полиморфный.
Разделение запроса и модификатора.
Описание: Есть метод, возвращающий значение, но также и изменяющий состояние объекта.
Действие: Создать 2 метода – один для запроса, другой – для модификации.
Параметризация метода.
Описание: Несколько методов выполняют сходные действия, но с разными значениями, содержащимися в теле метода.
Действие: Создать один метод, к-ый использует для задания разных значений параметр.
Void DiscountForMen()
Void DiscountForWomen()
-------------------------
void Discount( char cSex )
Замена параметра явными методами.
Описание: Есть метод, выполняющий разные действия в зависимости от значения параметра перечислимого типа.
Действие: Создать отдельный метод для каждого значения параметра.
Сохранение всего объекта.
Описание: В качестве параметров при вызове метода передаются несколько значений объекта.
Действие: Передавать весь объект.
Замена параметра вызовом метода.
Описание: Объект вызывает метод, а затем передает полученный результат в качестве параметра метода.
Действие: Убрать параметр и заставить получателя вызывать этот метод.
Int price = _quantity * itemPrice;
Double DiscountLevel = GetDiscountLevel();
Double finalPrice = GetDiscount( price, discountLevel );
-----------------------------------------------
Int price = _quantity * itemPrice;
Double finalPrice = GetDiscount( price );
Введение граничного объекта (Introduce Parameter Object).
Описание: Есть набор параметров, связанных друг с другом.
Действие: Заменить их объектом.
Удаление метода установки значения.
Описание: Поле должно быть установлено в момент создания и больше никогда не изменяться.
Действие: Удалить методы, устанавливающие значение этого поля (устанавливать в конструкторе).
Сокрытие метода.
Описание: Метод не используется никаким другим классом.
Действие: Сделать метод закрытым.
Замена конструктора фабричным методом.
Инкапсуляция нисходящего преобразования типа.
Замена кода ошибки исключительной ситуацией.
Замена исключительной ситуации проверкой.
ЛЕКЦИЯ 11. Рефакторинг. Реорганизация условных выражений.
Декомпозиция условного оператора.
Описание: Имеется сложная условная цепочка проверок.
Действие: Выделить методы из условия, частей THEN и ELSE.
If (( day>15 ) && ( day < 31 )) {
C = a*b + d; }
-------------------------------------------------
if ( dayFits() ) c = Calculate();
Консолидация условного выражения.
Описание: Есть ряд проверок условия, дающих одинаковый результат.
Действие: Объединить их в одно условное выражение и выделить его.
Double DisabilityAmount() {
If ( quantity < 5 ) return 0;
If ( months > 12 ) return 0;
// compute amount
}
--------------------------------------------------
Double DisabilityAmount() {
If ( IsNotDisabilityNeeded ) return 0;
// compute amount
}