Base/Knowledges/IT/Рефакторинг/Методы рефакторинга/Отделение запроса от модификатора (Separate Query from Modifier).md
2026-02-23 19:52:05 +03:00

48 lines
4.9 KiB
Markdown
Raw Permalink 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 20250212082457.png]]
### **Проблема**
У вас есть метод, который возвращает какое-то значение, но при этом в процессе работы он изменяет что-то внутри объекта
```typescript
function getTotalOutstandingAndSendBill() {
const result = customer.invoices.reduce((total, each) => each.amount + total, 0);
sendBill();
return result;
}
```
### **Решение**
Разделите метод на два разных метода. Один из них пускай возвращает значение, а второй модифицирует объект.
```typescript
function totalOutstanding() {
return customer.invoices.reduce((total, each) => each.amount + total, 0);
}
function sendBill() {
emailGateway.send(formatBill(customer));
}
```
### **Причины рефакторинга**
Этот рефакторинг является реализацией принципа разделения команд от запросов данных. Суть принципа сводится к тому, чтобы отделять код получения каких-то данных от кода, который изменяет что-то внутри объекта.
Код получения данных называют запросами, а код изменения видимого состояния объекта — модификаторами. Когда запрос и модификатор совмещены, у вас нет способа получить данные из объекта без того, чтобы не внести изменения в его состояние. Другими словами, вы задаёте вопрос и можете изменить ответ прямо в процессе его получения. Усугубляется эта проблема тем, что человек, вызывающий запрос, может не знать о «побочных действиях» такого метода, что нередко приводит к ошибкам выполнения программы.
Однако стоит подчеркнуть, что «побочными действиями» опасны только те модификаторы, которые меняют видимое состояние объекта. Это, например, поля, которые доступны из публичного интерфейса объекта, записи в базе данных, в файлах и т. д. Если какой-то модификатор всего лишь кеширует какую-то сложную операцию и сохраняет её внутри приватного поля класса, он вряд ли приведёт к «побочным действиям».
### **Достоинства**
- Если у вас есть запрос, который не меняет состояние программы, вы можете вызывать его сколько угодно раз, не опасаясь того, что результат изменится от самого факта вызова метода.
### Недостатки
- В некоторых случаях, удобно возвращать какие-то данные после осуществления команды. Например, удаляя что-то из базы данных, вы хотите узнать, сколько при этом строк было удалено.
### **Порядок рефакторинга**
1. Создайте новый метод-запрос, который бы возвращал то, что возвращал оригинальный метод.
2. Сделайте так, чтобы оригинальный метод возвращал только результат вызова нового метода-запроса.
3. Замените все обращения к оригинальному методу вызовом метода-запроса. Непосредственно перед этой строкой нужно вставить вызов метода-модификатора. Это убережёт вас от побочных действий в случае, если оригинальный метод использовался в описании условных операторов и циклов.
4. Избавьтесь от кода возврата значения в оригинальном методе. После этого он станет правильным методом-модификатором.
### **Ссылки**
- https://refactoring.guru/ru/separate-query-from-modifier
- [[Мартин Фаулер - Рефакторинг кода на JavaScript]]