Иммутабельные объекты в PHP

Класс, содержащий любые методы (не конструктор), которые изменяют любые данные в объекте класса, называется мутабельным.

"Mutable" означает, что что-то может быть изменено, а "Immutable" - что что-то неизменно.

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

При реализации иммутабельных объектов необходимо:

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

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

Пример мутабельного (mutable) класса

class Car
{
    /**
     * @var string
     */
    private $color;

    /**
     * @param string $color
     *
     * @return Car
     */
    public function setColor(string $color): Car
    {
        $this->color = $color;
        return $this;
    }

    /**
     * @return string
     */
    public function getColor(): string
    {
        return $this->color;
    }
}

Здесь мы видим метод setColor(), который изменяет состояние.

$car = new Car();
$car->setColor('red');
$car->setColor('green');
$car->setColor('black');

В этом случае мы изменяем состояние нашего объекта PHP после его инициализации. На самом деле мы можем делать это столько раз, сколько захотим.

Пример неизменяемого (Iimmutable) класса

class Car
{
    /**
     * @var string
     */
    private $color;

    /**
     * Car constructor.
     *
     * @param string $color
     */
    public function __construct(string $color)
    {
        $this->color = $color;
    }

    /**
     * @return string
     */
    public function getColor(): string
    {
        return $this->color;
    }
}

$car = new Car('red');

В этом случае наш объект PHP является неизменяемым. Мы не можем изменить его после инициализации.

Надеюсь, эти два простых примера объяснят основную разницу.

Написать комментарий