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

4.9 KiB
Raw Blame History

#рефакторинг #методы_рефакторинга

!Pasted image 20250212082457.png

Проблема

У вас есть метод, который возвращает какое-то значение, но при этом в процессе работы он изменяет что-то внутри объекта

function getTotalOutstandingAndSendBill() {
  const result = customer.invoices.reduce((total, each) => each.amount + total, 0);
  sendBill();
  return result;
}

Решение

Разделите метод на два разных метода. Один из них пускай возвращает значение, а второй модифицирует объект.

function totalOutstanding() {
  return customer.invoices.reduce((total, each) => each.amount + total, 0);  
}

function sendBill() {
  emailGateway.send(formatBill(customer));
}

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

Этот рефакторинг является реализацией принципа разделения команд от запросов данных. Суть принципа сводится к тому, чтобы отделять код получения каких-то данных от кода, который изменяет что-то внутри объекта.

Код получения данных называют запросами, а код изменения видимого состояния объекта — модификаторами. Когда запрос и модификатор совмещены, у вас нет способа получить данные из объекта без того, чтобы не внести изменения в его состояние. Другими словами, вы задаёте вопрос и можете изменить ответ прямо в процессе его получения. Усугубляется эта проблема тем, что человек, вызывающий запрос, может не знать о «побочных действиях» такого метода, что нередко приводит к ошибкам выполнения программы.

Однако стоит подчеркнуть, что «побочными действиями» опасны только те модификаторы, которые меняют видимое состояние объекта. Это, например, поля, которые доступны из публичного интерфейса объекта, записи в базе данных, в файлах и т. д. Если какой-то модификатор всего лишь кеширует какую-то сложную операцию и сохраняет её внутри приватного поля класса, он вряд ли приведёт к «побочным действиям».

Достоинства

  • Если у вас есть запрос, который не меняет состояние программы, вы можете вызывать его сколько угодно раз, не опасаясь того, что результат изменится от самого факта вызова метода.

Недостатки

  • В некоторых случаях, удобно возвращать какие-то данные после осуществления команды. Например, удаляя что-то из базы данных, вы хотите узнать, сколько при этом строк было удалено.

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

  1. Создайте новый метод-запрос, который бы возвращал то, что возвращал оригинальный метод.
  2. Сделайте так, чтобы оригинальный метод возвращал только результат вызова нового метода-запроса.
  3. Замените все обращения к оригинальному методу вызовом метода-запроса. Непосредственно перед этой строкой нужно вставить вызов метода-модификатора. Это убережёт вас от побочных действий в случае, если оригинальный метод использовался в описании условных операторов и циклов.
  4. Избавьтесь от кода возврата значения в оригинальном методе. После этого он станет правильным методом-модификатором.

Ссылки