Назад к вопросам
Middle+
161
questionbank

Как связаны между собой иммутабельность и чистота?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Иммутабельность (неизменяемость объектов) и чистота (функции, не имеющие побочных эффектов) тесно связаны, так как иммутабельность способствует достижению чистоты.

Чистая функция:

  • Всегда возвращает один и тот же результат для одних и тех же входных данных.
  • Не изменяет состояние вне своей области видимости (не имеет побочных эффектов).

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

Используя иммутабельные объекты:

  • Функция не может изменить переданные ей объекты, так как они являются неизменяемыми.
  • Любое "изменение" приводит к созданию нового объекта, а не к модификации существующего.
  • Это гарантирует отсутствие побочных эффектов, связанных с изменением переданных аргументов.

Пример:

<?php

// Изменяемый объект
class MutablePoint {
    public $x;
    public $y;

    public function __construct($x, $y) {
        $this->x = $x;
        $this->y = $y;
    }
}

// Нечистая функция (изменяет переданный объект)
function moveMutablePoint(MutablePoint $point, $dx, $dy) {
    $point->x += $dx;
    $point->y += $dy;
}

$mutablePoint = new MutablePoint(0, 0);
moveMutablePoint($mutablePoint, 1, 1);
// $mutablePoint теперь (1, 1) - состояние изменилось вне функции

// Иммутабельный объект
final class ImmutablePoint {
    private $x;
    private $y;

    public function __construct($x, $y) {
        $this->x = $x;
        $this->y = $y;
    }

    public function getX(): int {
        return $this->x;
    }

    public function getY(): int {
        return $this->y;
    }

    // Метод возвращает НОВЫЙ объект, а не изменяет текущий
    public function move($dx, $dy): self {
        return new self($this->x + $dx, $this->y + $dy);
    }
}

// Чистая функция (работает с иммутабельными объектами)
function moveImmutablePoint(ImmutablePoint $point, $dx, $dy): ImmutablePoint {
    return $point->move($dx, $dy);
}

$immutablePoint = new ImmutablePoint(0, 0);
$newImmutablePoint = moveImmutablePoint($immutablePoint, 1, 1);
// $immutablePoint остался (0, 0) - состояние не изменилось вне функции
// $newImmutablePoint теперь (1, 1) - создан новый объект

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