Весенняя РАСПРОДАЖА

Извлечение класса

Также известен как: Extract Class

Проблема

Один класс работает за двоих.

Решение

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

До
Extract Class - Before
После
Extract Class - After

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

Классы всегда изначально выглядят чёткими и понятными. Они выполняют свою работу и не лезут в обязанности других классов. Однако, с течением жизни программы добавляется один метод  — тут, одно поле  — там. В результате некоторые классы получают массу дополнительных обязанностей.

Достоинства

  • Этот рефакторинг призван помочь в соблюдении принципа единственной обязанности класса. Это делает код ваших классов очевиднее и понятнее.

  • Классы с единственной обязанностью более надёжны и устойчивы к изменениям. Например, у вас есть класс, отвечающий за десять разных вещей. И когда вам придётся вносить в него изменения, вы рискуете при корректировках одной вещи сломать другие.

Недостатки

  • Если при проведении этого рефакторинга вы перестараетесь, придётся прибегнуть к встраиванию класса.

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

Перед началом рефакторинга обязательно определите, как именно следует разделить обязанности класса.

  1. Создайте новый класс, который будет содержать выделенную функциональность.

  2. Создайте связь между старым и новым классом. Лучше всего, если эта связь будет односторонней; при этом второй класс можно будет без проблем использовать повторно. С другой стороны, если вы считаете, что это необходимо, всегда можно создать двустороннюю связь.

  3. Используйте перемещение поля и перемещение метода для каждого поля и метода, которые вы решили переместить в новый класс. Для методов имеет смысл начинать с приватных, таким образом вы снижаете вероятность допустить массу ошибок. Старайтесь двигаться понемногу и тестировать результат после каждого перемещения, это избавит вас от необходимости исправлять большое число ошибок в самом конце.

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

  4. Ещё одним нюансом является доступность нового класса извне. Вы можете полностью спрятать его от клиента, сделав приватным, управляя при этом его полями из старого класса. Либо сделать его публичным, предоставив клиенту возможность напрямую менять значения. Решение зависит от того, насколько безопасны для поведения старого класса будут неожиданные прямые изменения значений в новом классе.