Autumn SALE

Замена подкласса полями

Также известен как: Replace Subclass with Fields

Проблема

У вас есть подклассы, которые отличаются только методами, возвращающими данные-константы.

Решение

Замените методы полями в родительском классе и удалите подклассы.

До
Replace Subclass with Fields - Before
После
Replace Subclass with Fields - After

Причины рефакторинга

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

В одном из подобных случаев иерархия подклассов может отличаться только значениями, возвращаемыми определёнными методами. Причём эти значения не являются результатом вычисления, а жёстко прописаны либо в самих методах, либо в полях, возвращаемых методами. Чтобы упростить архитектуру классов, такая иерархия может быть свёрнута в один класс, содержащий одно или несколько полей с нужными значениями в зависимости от ситуации.

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

Достоинства

  • Упрощает архитектуру системы. Создание подклассов — слишком избыточное решение, если все, что нужно сделать, это возвращать разные значения в нескольких методах.

Порядок рефакторинга

  1. Примените к подклассам замену конструктора фабричным методом.

  2. Замените вызовы конструкторов подклассов вызовами фабричного метода суперкласса.

  3. Объявите в суперклассе поля для хранения значений каждого из методов подклассов, возвращающих константные значения.

  4. Создайте защищённый конструктор суперкласса для инициализации новых полей.

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

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

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

  8. Удалите подкласс.