#рефакторинг #методы_рефакторинга ![[Pasted image 20250220082420.png]] ### **Проблема** У вас есть подкласс, который использует только часть методов суперкласса или не хочет наследовать его данные. ```javascript class Order { get daysToShip() { return this._warehouse.daysToShip; } } class PriorityOrder extends Order { get daysToShip() { return this._priorityPlan.daysToShip; } } ``` ### **Решение** Создайте поле и поместите в него объект суперкласса, делегируйте выполнение методов объекту-суперклассу, уберите наследование. ```javascript class Order { get daysToShip() { return (this._priorityDelegate) ? this._priorityDelegate.daysToShip : this._warehouse.daysToShip; } } class PriorityOrderDelegate { get daysToShip() { return this._priorityPlan.daysToShip } } ``` ### **Причины рефакторинга** Замена наследования композицией может значительно улучшить дизайн классов, если: - Ваш подкласс нарушает [[Принцип подстановки Лисков| принцип замещения Барбары Лисков]]. Другими словами, наследование возникло только ради объединения общего кода, но не потому, что подкласс «является» (is-a) расширением суперкласса. - Подкласс использует только часть методов суперкласса. В этом случае, это только вопрос времени, пока кто-то не вызовет метод суперкласса, который он не должен был вызывать. Суть рефакторинга сводится к тому, чтобы разделить оба класса, и сделать суперкласс помощником подкласса, а не его родителем. Вместо того чтобы наследовать все методы суперкласса, подкласс будет иметь только необходимые методы, которые будут делегировать выполнение методам объекта-суперкласса. ### **Достоинства** - Класс не содержит лишних методов, которые достались ему в наследство от суперкласса. - В поле-делегат можно подставлять разные объекты, имеющие различные реализации функциональности. По сути, вы получаете реализацию паттерна проектирования [[Стратегия]]. ### **Недостатки** ### **Порядок рефакторинга** 1. Создайте поле в подклассе для содержания суперкласса. На первом этапе поместите в него текущий объект. 2. Измените методы подкласса так, чтобы они использовали объект суперкласса, вместо this. 3. Для методов, которые были унаследованы из суперкласса и которые вызываются в клиентском коде, в подклассе нужно создать простые делегирующие методы. 4. Уберите объявление наследования из подкласса 5. Измените код инициализации поля, в котором хранится бывший суперкласс, созданием нового объекта ### **Обратный рефакторинг** - [[Замена суперкласса делегатом (Replace Superclass with Delegate)]] ### **Ссылки** - https://refactoring.guru/ru/replace-inheritance-with-delegation - [[Мартин Фаулер - Рефакторинг кода на JavaScript]]