Неизменный объект со многими свойствами - PullRequest
0 голосов
/ 11 мая 2018

У меня есть класс, который я хочу сделать неизменным, но у этого класса есть много свойств.

<?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() со всеми этими свойствами, он будет раздутым. Если я представлю сеттеры, это больше не будет неизменным.


РЕДАКТИРОВАТЬ: Я думал о создании сеттеров, но те, которые могут быть использованы только один раз. Благодаря этому у меня не будет раздутого конструктора, но по какой-то причине это кажется не очень хорошей идеей. Что-то вроде:

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';
    }

}

Ответы [ 2 ]

0 голосов
/ 11 мая 2018

Я бы использовал __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";

PS : исключения должны расширять базовый класс исключений , или вы можете вызвать или log ошибку, зависит от того, чтоВы хотите

PSS : альтернативным решением было бы использование __ call () метода и проверка, если значение равно нулю

0 голосов
/ 11 мая 2018

Я бы предложил передать свойства в качестве аргумента массива, например

__construct( array $properties )
{
  $this->property = $properties['property'];
  ....
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...