Глянь мой новый курс по Git! Привет! Глянь мой новый курс по Git! Привет! Глянь мой новый курс по Git на GitByBit.com! Привет! Хочешь круто подтянуть Git? Глянь мой новый курс на GitByBit.com!

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

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

Проблема

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

Решение

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

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

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

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

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

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

Достоинства

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

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

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

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

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

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

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

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

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