Это нарушает неизменность объекта? - PullRequest
0 голосов
/ 01 декабря 2018

Я читал это: 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 само значение нарушает неизменность, верно?:)

Ответы [ 3 ]

0 голосов
/ 01 декабря 2018

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

0 голосов
/ 01 декабря 2018

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

  private $mutable = true;

И позже (при построении) меняя это значение на false затем:

 private $skater

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

private $skater = null;

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

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

0 голосов
/ 01 декабря 2018

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

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

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...