我有一个类,我想使其不可变,但该类有很多属性。
<?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或者你可以trigger或log一个错误,取决于你想要什么
P.S.S:另一种解决方案是使用 __call()方法并检查值是否为 null
关于php - 具有许多属性的不可变对象(immutable对象),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50293453/