php - 具有许多属性的不可变对象(immutable对象)

标签 php immutability

我有一个类,我想使其不可变,但该类有很多属性。

<?php

class Gameworld {

    /** @var string */
    private $name;

    /** @var string */
    private $type;

    /** @var bool */
    private $is_online;

    /** @var int */
    private $online_players;

    /** @var int */
    private $online_players_record;

    /** @var string */
    private $description;

    /** @var string */
    private $location;

    /** @var \DateTime */
    private $created_at;

}

如何创建这样的对象?当我引入带有所有这些属性的 public function __construct() 时,它会变得臃肿。如果我引入 setter ,它就不再是不可变的了。


编辑:我正在考虑制作只能使用一次的 setter 。多亏了这一点,我不会有臃肿的构造函数,但出于某种原因,这似乎不是一个好主意。就像是:

class Gameworld {

    ... old properties ...

    /** @var array */
    private $used_setters = [];

    public function setName(string $name){
        if(in_array('name', $this->used_setters)){
            throw new ImmutableException('Class Gameworld is immutable.');
        }

        $this->name = $name;
        $this->used_setters[] = 'name';
    }

}

最佳答案

我会使用__set()检查值是否已设置的魔术方法,否则我会抛出异常:

class Gameworld {

    /** @var string */
    private $name;

    /** @var string */
    private $type;

    /** @var bool */
    private $is_online;

    /** @var int */
    private $online_players;

    /** @var int */
    private $online_players_record;

    /** @var string */
    private $description;

    /** @var string */
    private $location;

    /** @var \DateTime */
    private $created_at;

    public function __set($property, $value)  
    {  
        if (property_exists($this, $property)) {  
            if(is_null($this->$property)){
                $this->$property = $value;
                return $this;
            }
            throw MyCustomException();
        }
        throw UndefinedClassVariableException();
    }
}

基本用法是:

$x = new Gameworld();
$x->name = "OK";
$x->is_online = true;
$x->name="Exception";

P.S:异常(exception)情况必须extend the base exception class或者你可以triggerlog一个错误,取决于你想要什么

P.S.S:另一种解决方案是使用 __call()方法并检查值是否为 null

关于php - 具有许多属性的不可变对象(immutable对象),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50293453/

相关文章:

php - 在不预先知道 ID 名称的情况下,如何在 php 中获取按钮的 ID

java.lang.UnsupportedOperationException ImmutableList.remove 当我没有使用 ImmutableList 时

python - 如何在 python 中使类不可变?

javascript - 为什么在 React 中调用 'setState()' 时使用扩展运算符?

php - 如何在php中将十六进制转换为字符串或文本

javascript - 当字段丢失时,如何使用 php 或 js 回显默认文本?

java - 如何在 MySQL 中预测/计算数值 (INT) 的字段长度?

php - 如何修复此代码(由于 MySql 已弃用)

javascript - Angular2 ngModel : Why can it change an immutable string?

java - 当我将可变对象变成不可变对象(immutable对象)时,方法名称应该如何更改?