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

Если в классе есть публичное свойство, означает ли это, что класс является иммутабельным?

Sobes Copilot

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

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

sobes.tech AI

Нет.

Публичное свойство в классе означает, что значение этого свойства может быть изменено извне объекта. Иммутабельный объект — это тот, состояние (значения его свойств) которого не может быть изменено после создания. Наличие публичного свойства противоречит принципу иммутабельности.

Для достижения иммутабельности класс должен соответствовать следующим условиям:

  • Все свойства должны быть закрытыми (private) или защищенными (protected).
  • Не должно быть сеттеров (методов, изменяющих значения свойств).
  • Все зависимости (объекты, с которыми работает данный класс) также должны быть иммутабельными или их состояние не должно изменяться извне.
  • Конструктор должен полностью инициализировать объект и его нельзя изменить после создания.
  • Если требуются изменения, должны создаваться новые экземпляры объекта с новыми значениями.

Пример класса с публичным свойством (мутабельный):

<?php
class MutableObject
{
    public $value; // Публичное свойство

    public function __construct($value)
    {
        $this->value = $value;
    }
}

$obj = new MutableObject(10);
echo $obj->value; // 10

$obj->value = 20; // Значение изменено извне
echo $obj->value; // 20

Пример реализации иммутабельного класса:

<?php
class ImmutableObject
{
    private $value; // Закрытое свойство

    public function __construct($value)
    {
        $this->value = $value;
    }

    public function getValue() : int
    {
        return $this->value;
    }

    // Метод для "изменения", фактически создает новый объект
    public function withValue(int $newValue) : self
    {
        return new self($newValue);
    }
}

$obj1 = new ImmutableObject(10);
echo $obj1->getValue(); // 10

// $obj1->value = 20; // Ошибка: Cannot access private property ImmutableObject::$value

$obj2 = $obj1->withValue(20); // Создается новый объект
echo $obj1->getValue(); // 10 (исходный объект не изменился)
echo $obj2->getValue(); // 20 (новый объект с измененным значением)