Autumn SALE

Введение локального расширения

Также известен как: Introduce Local Extension

Проблема

В служебном классе отсутствуют некоторые методы, которые вам нужны. При этом добавить их в этот класс вы не можете.

Решение

Создайте новый класс, который бы содержал эти методы, и сделайте его наследником служебного класса, либо его обёрткой.

До
Introduce Local Extension - Before
После
Introduce Local Extension - After

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

В классе, который вы используете, нет нужных вам методов. Или ещё хуже — вы не можете их туда добавить (например, потому что классы находятся в сторонней библиотеке). У вас есть два пути:

  • Создать подкласс из интересующего класса, который будет содержать новые методы, и наследовать все остальное из родительского класса. Этот путь проще, но иногда бывает заблокирован в самом служебном классе с помощью директивы final.

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

Достоинства

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

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

  1. Создайте новый класс-расширение:

    • либо сделайте его наследником служебного класса;

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

  2. Создайте конструктор, использующий параметры конструктора служебного класса.

  3. Кроме того, создайте альтернативный «конвертирующий» конструктор, который принимает в параметрах только объект оригинального класса. Это поможет в подстановке расширения вместо объектов оригинального класса.

  4. Создайте в классе новые расширенные методы. Переместите в него внешние методы из других классов, либо удалите их, если расширение уже имеет такой функционал.

  5. Замените использование служебного класса новым классом-расширением в тех местах, где нужна расширенная функциональность.