Это нарушает неизменность объекта?

Я читал это: https://www.simonholywell.com/post/2017/03/php-and-immutability/

и натолкнулся на пример, так что это идеальный неизменный класс:

class Immutable {
private $skater, $trick;

public function __construct($skater, $trick) {
$this->skater = $skater;
$this->trick = $trick;
}

public function getSkater() {
return $this->skater;
}

public function getTrick() {
return $this->trick;
}
}

Все идет нормально. Но не ломается, как упоминалось в статье:

$x = new Immutable('Hawk', 'Frontside 540');
$x->__construct('Song', 'Darkslide');

это было переписано так:

class Immutable {
private $skater, $trick;
private $mutable = true;

public function __construct($skater, $trick) {
if (false === $this->mutable) {
throw new \BadMethodCallException('Constructor called twice.');
}
$this->skater = $skater;
$this->trick = $trick;
$this->mutable = false;
}

public function getSkater() {
return $this->skater;
}

public function getTrick() {
return $this->trick;
}
}

но сейчас меняется mute само значение нарушает неизменность, верно? 🙂

0

Решение

Нет, это не так, поскольку значение устанавливается только в конструкторе и никогда не изменяется впоследствии. Так что это соответствует определению неизменности. Я бы переименовал $mutable в $isCreated или что-то, потому что вы не можете изменить изменяемое свойство класса с этим свойством, по моему мнению, оно неверно названо.

На некотором уровне, однако, неизменность объекта в PHP вообще невозможна, потому что:

Неизменность не означает, что объект, хранящийся в памяти компьютера, не подлежит записи. Скорее, неизменяемость — это конструкция времени компиляции, которая указывает, что программист может делать через обычный интерфейс объекта, а не обязательно то, что он может делать абсолютно.

(Источник: Википедия)

Так как в PHP нет «времени компиляции» и $mutable свойство оценивается во время выполнения, казалось бы, нарушать эту концепцию с самого начала.

На другом уровне, используя ту же цитату, «нормальный интерфейс» будет тем, что представляет ваш первый пример. Вызов метода конструктора напрямую, а не через new полностью вне любого нормального использования. Таким образом, вы могли бы сказать, что класс без установщиков его свойств уже неизменен по соглашению «через обычный интерфейс».

По сути, вы задаете академический вопрос, но пытаетесь решить реальную проблему абсолютной уверенности, что свойства объекта не могут быть изменены ни при каких обстоятельствах после создания экземпляра. Но тогда понятие «неизменность» не применимо.

2

Другие решения

Нет принципиальной разницы между:

  private $mutable = true;

А потом (при строительстве) изменив это на false затем:

 private $skater

А потом поменять это на что-то другое позже (при строительстве). Когда вы не устанавливаете начальное значение, вы говорите:

private $skater = null;

Вы можете легко проверить это, выполнив var_dump($this->skater) перед установкой значения, и он скажет null, Так что в действительности в первом примере вы уже меняете нулевое значение на что-то другое. песочница Так на самом деле какая разница между изменением null и меняется false на строительстве?

Скорее всего, вы считаете, что неизменность — это вопрос мнения. Единственное, что в PHP является неизменным, это константы.

1

Пока ваш неизменный класс принимает только примитивные типы данных (такие как string, int, float, bool), ваш класс должен быть достаточно неизменным. Но как только вы передаете объекты или потоки, это не является неизменным. Даже с Объектами Значения нелегко получить истинный неизменный объект.

0
По вопросам рекламы [email protected]