Sobes.tech
Middle+

Jak są ze sobą powiązane niezmienność i czystość?

sobes.tech AI

Odpowiedź od AI

Niezmienność (obiekty niezmienialne) i czystość (funkcje bez efektów ubocznych) są ściśle powiązane, ponieważ niezmienność sprzyja osiągnięciu czystości.

Czysta funkcja:

  • Zawsze zwraca ten sam wynik dla tych samych danych wejściowych.
  • Nie zmienia stanu poza swoim zakresem (nie ma efektów ubocznych).

Jeśli funkcja przyjmuje jako argumenty obiekty zmienne i je modyfikuje, nie jest czysta, ponieważ jej wywołanie może zmienić stan systemu poza funkcją.

Używając obiektów niezmienialnych:

  • Funkcja nie może zmienić przekazanych obiektów, ponieważ są niezmienialne.
  • Każda "zmiana" prowadzi do utworzenia nowego obiektu, a nie do modyfikacji istniejącego.
  • To gwarantuje brak efektów ubocznych związanych z modyfikacją przekazanych argumentów.

Przykład:

<?php

// Obiekt zmienny
class MutablePoint {
    public $x;
    public $y;

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

// Funkcja nie czysta (modyfikuje przekazany obiekt)
function moveMutablePoint(MutablePoint $point, $dx, $dy) {
    $point->x += $dx;
    $point->y += $dy;
}

$mutablePoint = new MutablePoint(0, 0);
moveMutablePoint($mutablePoint, 1, 1);
// $mutablePoint teraz jest (1, 1) - stan zmienił się poza funkcją

// Obiekt niezmienny
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;
    }

    // Metoda zwraca NOWY obiekt, nie zmienia obecnego
    public function move($dx, $dy): self {
        return new self($this->x + $dx, $this->y + $dy);
    }
}

// Funkcja czysta (pracuje z obiektami niezmienialnymi)
function moveImmutablePoint(ImmutablePoint $point, $dx, $dy): ImmutablePoint {
    return $point->move($dx, $dy);
}

$immutablePoint = new ImmutablePoint(0, 0);
$newImmutablePoint = moveImmutablePoint($immutablePoint, 1, 1);
// $immutablePoint pozostaje (0, 0) - stan nie zmienił się poza funkcją
// $newImmutablePoint jest teraz (1, 1) - utworzono nowy obiekt

Użycie obiektów niezmienialnych jest jednym ze sposobów tworzenia funkcji czystych, co przyczynia się do bardziej przewidywalnego, testowalnego i łatwego w utrzymaniu kodu.