Идемпотентность в программировании

Идемпотентность в программировании

Идемпотентность в программировании — это свойство операции, при котором повторное выполнение этой операции приводит к тому же результату, что и первое выполнение. То есть, независимо от того, сколько раз вы вызываете операцию, эффект остаётся неизменным.

Пример из реальной жизни:

Стоишь в подъезде и нажимаешь на кнопку лифта (если конечно пизд*ки не спалили тебе кнопку лифта). Кнопка загорелась, лифт поехал к тебе. Ты нажимаешь кнопку ещё 10 раз, но лифт уже вызван и едет к тебе. Поведение системы не меняется, сколько ты не нажал эту кнопку.

Пример при разработке REST API:

У тебя есть метод для удаления товара из избранного DELETE /favourite/product/1. Пользователь кликнул на иконку ❤ и ушёл запрос на удаления товара из избранного, запрос могло подглючить и пользователь ещё раз нажал на иконку. Вот на сервер полетело два запроса. Отработал первый запрос и выдал код HTTP код 200. Товара уже нет в избранном. Далее начинает отрабатывать второй запрос, но товара уже нет в избранном и тут два пути. Выдать ошибку с HTTP кодом 400, что товара нет в избранном или просто проверить на сервере, что товара уже нет в избранном и отдать HTTP 200. В данном случаем второй вариант более приемлемый, т.к. поведение системы понятно и нам в общем не интересно, был ли товар в избранном или нет.

Пример кода:

Например, у нас есть метод который возвращет "Доброе утро", "Добрый день", "Добрый вечер"

function getGreetingMessage() { $currentTime = new DateTime(); $hour = (int)$currentTime->format('H'); if ($hour < 12) { return "Доброе утро!"; } elseif ($hour < 18) { return "Добрый день!"; } else { return "Добрый вечер!"; } }

Как видим, мы можем его вызвать несколько раз и в разное время получить разные результат. Это очень плохо и у нас нет контроля над функцией. Давайте переделаем этот метод

function getGreetingMessage(\DateTime $datetime) { $hour = (int)$datetime->format('H'); if ($hour < 12) { return "Доброе утро!"; } elseif ($hour < 18) { return "Добрый день!"; } else { return "Добрый вечер!"; } }

Теперь мы контролируем поведение функции, т.к. мы если мы будет вызывать эту функцию много раз с одним и тем же параметром, результат работы функции не изменится.

Чтобы добиться идемпотентности в коде, разработчики могут использовать различные подходы:

  • Неизменяемые данные: Использование неизменяемых объектов, которые не могут быть изменены после создания.
  • Контроль состояния: Проверка текущего состояния перед выполнением операции и выполнение только если это необходимо.
  • Обработка ошибок: Предусмотрительная обработка ошибок, чтобы операция либо завершалась успешно, либо никак не изменяла состояние системы.
2
2 комментария