Sobes.tech
Middle+

Как са свързани неизменяемостта и чистотата?

sobes.tech AI

Отговор от 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) - създаден е нов обект

Използването на непроменяеми обекти е един от начините за създаване на чисти функции, което допринася за по-предсказуем, тестируем и лесен за поддръжка код.