62 lines
5.7 KiB
Markdown
62 lines
5.7 KiB
Markdown
#рефакторинг #методы_рефакторинга
|
||
|
||
![[Pasted image 20250127094845.png]]
|
||
|
||
### **Проблема**
|
||
Один класс работает за двоих
|
||
```javascript
|
||
class Person {
|
||
|
||
get officeAreaCode() {return this._officeAreaCode;}
|
||
get officeNumber() {return this._officeNumber;)
|
||
|
||
}
|
||
```
|
||
|
||
### **Решение**
|
||
Создайте новый класс, переместите в него поля и методы, отвечающие за определённую функциональность.
|
||
```javascript
|
||
class Person {
|
||
get officeAreaCode() {return this._telephoneNumber.areaCode;}
|
||
get officeNumber() {return this,_telephoneNumber.number;}
|
||
}
|
||
|
||
class TelephoneNumber {
|
||
get areaCode() {return this._areaCode;}
|
||
get number() (return this._number;}
|
||
}
|
||
```
|
||
|
||
### **Причины рефакторинга**
|
||
Классы всегда изначально выглядят чёткими и понятными. Они выполняют свою работу и не лезут в обязанности других классов. Однако, с течением жизни программы добавляется один метод — тут, одно поле — там. В результате некоторые классы получают массу дополнительных обязанностей.
|
||
|
||
### **Достоинства**
|
||
- Этот рефакторинг призван помочь в соблюдении принципа единственной обязанности . Это делает код ваших классов очевиднее и понятнее.
|
||
- Классы с единственной обязанностью более надёжны и устойчивы к изменениям. Например, у вас есть класс, отвечающий за десять разных вещей. И когда вам придётся вносить в него изменения, вы рискуете при корректировках одной вещи сломать другие.
|
||
|
||
### **Недостатки**
|
||
- Если при проведении этого рефакторинга вы перестараетесь, придётся прибегнуть к [[Встраивание класса (Inline Class)|встраиванию класса]].
|
||
|
||
### **Порядок рефакторинга**
|
||
Перед началом рефакторинга обязательно определите, как именно следует разделить обязанности класса.
|
||
1. Создайте новый класс, который будет содержать выделенную функциональность
|
||
2. Создайте связь между старым и новым классом. Лучше всего, если эта связь будет односторонней; при этом второй класс можно будет без проблем использовать повторно. С другой стороны, если вы считаете, что это необходимо, всегда можно создать двустороннюю связь
|
||
3. Используйте [[Перемещение инструкций (Slide Statements)|перемещение поля]] и перемещение метода для каждого поля и метода, которые вы решили переместить в новый класс. Для методов имеет смысл начинать с приватных, таким образом вы снижаете вероятность допустить массу ошибок. Старайтесь двигаться понемногу и тестировать результат после каждого перемещения, это избавит вас от необходимости исправлять большое число ошибок в самом конце.
|
||
После того как с перемещением покончено, пересмотрите ещё раз на получившиеся классы. Возможно, старый класс теперь имеет смысл назвать по-другому ввиду его изменившихся обязанностей. Проверьте ещё раз, можно ли избавиться от двусторонней связи между классами, если она возникла.
|
||
4. Ещё одним нюансом является доступность нового класса извне. Вы можете полностью спрятать его от клиента, сделав приватным, управляя при этом его полями из старого класса. Либо сделать его публичным, предоставив клиенту возможность напрямую менять значения. Решение зависит от того, насколько безопасны для поведения старого класса будут неожиданные прямые изменения значений в новом классе
|
||
|
||
### **Борется с запахом**
|
||
- [[Дублируемый код]]
|
||
- [[Большой класс]]
|
||
- [[Расходящиеся изменения]]
|
||
- [[Группы данных]]
|
||
- [[Одержимость примитивами]]
|
||
- [[Временное поле]]
|
||
- [[Неуместная близость]]
|
||
|
||
### **Обратный рефакторинг**
|
||
- [[Встраивание класса (Inline Class)]]
|
||
|
||
### **Ссылки**
|
||
- https://refactoring.guru/ru/extract-class
|
||
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]] |