Base/Knowledges/IT/Рефакторинг/Методы рефакторинга/Замена подкласса делегатом (Replace Subclass with Delegate).md
2026-02-23 19:52:05 +03:00

65 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#рефакторинг #методы_рефакторинга
![[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]]