Иммутабельные объекты в 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 является неизменяемым. Мы не можем изменить его после инициализации.
Надеюсь, эти два простых примера объяснят основную разницу.