Замена подкласса полями.
У вас есть подклассы, которые отличаются только методами, возвращающими данные-константы.
Замените методы полями в родительском классе и удалите подклассы.
##Пример
abstract class Person {
abstract boolean isMale();
abstract char getCode();
}
class Male extends Person {
boolean isMale() { return true; }
char getCode() { return 'M'; }
}
class Female extends Person {
boolean isMale() { return false; }
char getCode() { return 'F'; }
}class Person {
private final boolean male;
private final char code;
private Person(boolean male, char code) {
this.male = male;
this.code = code;
}
static Person createMale() { return new Person(true, 'M'); }
static Person createFemale() { return new Person(false, 'F'); }
boolean isMale() { return male; }
char getCode() { return code; }
}##Зачем делать рефакторинг
Бывает так, что вам нужно развернуть действие рефакторинга избавления от кодирования типа.
В одном из подобных случаев иерархия подклассов может отличаться только значениями, возвращаемыми определёнными методами. Причём эти значения не являются результатом вычисления, а жёстко прописаны либо в самих методах, либо в полях, возвращаемых методами. Чтобы упростить архитектуру классов, такая иерархия может быть свёрнута в один класс, содержащий одно или несколько полей с нужными значениями в зависимости от ситуации.
Нужда в этих изменениях могла возникнуть после перемещения большого числа функциональностей из иерархии классов куда-то в другое место. После этого текущая иерархия потеряла свою ценность, и подклассы стали создавать только избыточную сложность.
##Преимущества
- Упрощает архитектуру системы. Создание подклассов — слишком избыточное решение, если все, что нужно сделать, это возвращать разные значения в нескольких методах.
##Как делать рефакторинг
-
Примените к подклассам замену конструктора фабричным методом.
-
Замените вызовы конструкторов подклассов вызовами фабричного метода суперкласса.
-
Объявите в суперклассе поля для хранения значений каждого из методов подклассов, возвращающих константные значения.
-
Создайте защищённый конструктор суперкласса для инициализации новых полей.
-
Создайте или модифицируйте имеющиеся конструкторы подклассов, чтобы они вызывали новый конструктор родительского класса и передавали в него соответствующие значения.
-
Реализуйте каждый константный метод в родительском классе так, чтобы он возвращал значение соответствующего поля, а затем удалите метод из подкласса.
-
Если конструктор подкласса имеет какую-то дополнительную функциональность, примените встраивание метода для встраивания его конструктора в фабричный метод суперкласса.
-
Удалите подкласс.