Доменный объект: сеттеры и геттеры или просто публичные свойства?

Должен ли я проверять свойства объекта домена, когда они устанавливаются?

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

Это как я должен проверять свойства объекта домена или я не должен проверять их вообще?

В последнем случае я могу просто удалить каждый установщик и получатель и просто сделать свойства объекта домена общедоступными, чтобы я мог просто взаимодействовать с ними напрямую.

class User
{
    private $id;
    private $firstname;
    private $lastname;
    private $email;
    private $password;
    private $registerDate;

    public function setId($id)
    {
        if (is_int($id)) {
            $this->id = $id;
        } else {
            throw new Exception('Parameter must be an integer.');
        }
    }

    public function setFirstname($firstname)
    {
        if (is_string($firstname)) {
            $this->firstname = $firstname;
        } else {
            throw new Exception('Parameter must be a string.');
        }
    }

    //{ etc setters }

    public function __get($property) {
        if (property_exists($this, $property)) {
            return $this->$property;
        }
    }
}

2 ответа

Решение

Проверка примитивных типов в динамическом, слабо типизированном языке кажется мне излишним в 99% случаев. Это действительно не имеет значения, если ваш $firstname является правильной строкой или нет, она будет в любом случае неявно преобразована в одну при необходимости.

Однако иногда имеет смысл проверить, соответствует ли значение примитива, переданного в качестве аргумента (не его тип, как вам известно), некоторым конкретным ограничениям бизнес-логики:

function squareRoot($number) {
    if(!is_numeric($number) || $number < 0)
        throw new \InvalidArgumentException("Positive number expected.");
    return sqrt($number);
}

Тем не менее, я буду использовать этот вид beaurocracy только тогда, когда это абсолютно необходимо. Если кто-то хочет передать нечисловую строку в метод с именем setNumber($number) с указанием типа документа $number это число, это его проблема, если плохие вещи случаются в результате.

С методами, ожидающими объект определенного типа (или реализующий определенный интерфейс) в качестве аргументов, используйте вместо этого подсказку типа:

function foo(BarObject $bar) {
    // ...
}

Это также работает с массивами:

function doStuffWithArray(array $a) {
    // ...
}

Интересно, что нет подсказки типа, которая позволила бы реализовывать как массивы, так и объекты. \ArrayAccess интерфейс, но это только одна из многих странностей PHP.

Мой совет - перенести логику проверки из сущностей в класс, который сохраняет их, будь то средство отображения данных, хранилище или что-то еще. Или, лучше, отдельный класс валидатора для каждого типа сущности / совокупного корня.

Зачем? Разделение проблем.

Давайте подумаем о проверке. Я вижу два вида валидаторов. Первый - проверка типа / диапазона, например, "Имя пользователя должно быть строковым и должно содержать от 5 до 50 символов". Второе - проверка, относящаяся к домену, например, "E-mail должен быть уникальным". Проверка домена может быть дорогостоящей и обычно требует много вспомогательных классов (сервисы, средства отображения данных, адаптеры баз данных и т. Д.).

Другие вопросы по тегам