@magary4

В чем преимущества ValueObject и DTO?

Посмотрел кучу материалов про этот паттерн везде обьясняют суть а вот зачем он я так и не пойму

ну допустим пусть сделаем

class DateRange {

function __counstruct( $from, $to ) {
   . . .
}

function getValue($name) {
    if($name != "from" and $name != "to" ) {
         throw new \Exception("");
    }

    return $this->{$name};
}


ну параметр в функцию надо будет передавать не два а один. поведения то никакого нет

второй вопрос про DTO
тоже читал про него
и понял что мой код

return $this->render($view, 
     array_map(function( $hit ) {
          return $hit->getVersionInfo()->getContenInfo();
     }, $searchResults);


в каком-то смысле я тоже редьюсю сложный обьект и передаю DTO во вьюшку верно?
вижу смысл ValueObject и DTO только если идет разработка расширяемого приложения чтоб гарантировать что разработчик передаст в нужную функцию обьект в котором доступен необходимое свойство
но вот внутри в тех частях логика которых фиксирована и не может меняться - вполне подходит массив ключ-значение

некоторое время назад я заметил что мои контроллеры часто возвращают массив с 3мя ключами content, searchResults, facets и даже думал дифинировать класс для такой структуры данных
но потом не стал - т.к. иногда нужен 4й ключ или даже 5й а если где-то не передан один из этих ключей - это сразу Exception и это правильно - система без них не может работать

и еще 3й вопрос
как реализовать на php типизированую коллекцию типа как в СИ

чтоб каждый элемента массива был одного определенного инстанса?

Всем Спасибо
  • Вопрос задан
  • 8273 просмотра
Решения вопроса 1
index0h
@index0h
PHP, Golang. https://github.com/index0h
Преимущество VO в том, что это значения, которые уже проверены на границы и тип. В вашем примере валидация происходит в геттере - это мягко говоря бессмысленно. Вот вам пример
class UUID
{
    /** @var string */
    private $value;

    /**
     * @param string $value
     */
    public function __construct(string $value)
    {
        if (!preg_match('/^[\da-f]{32}$/', $value)) {
            throw new \InvalidArgumentException(
                sprintf('Argument "$value" must be correct UUID, actual value: "%s"', $value)
            );
        }
        
        $this->value = $value;
    }

    /**
     * @return string
     */
    public function getValue(): string
    {
        return $this->value;
    }
}


Дальше в коде вам достаточно делать type hinting на тип VO и все, значение будет корректным. От рефлексии, или runkit вы все равно защититься не сможете.

-- --

DTO - это штука, для удобного транспорта данных, между разными частями системы. Например у вас есть метод, который на вход принимает 20+ аргументов (например регистрация), вызывать такое кодло вероятно будет не удобно, но собрав dto вы можете его передать одним аргументом и рассчитывать на то, что данные переданы с правильными типами. Граничные же значения придется проверить, так как в задачу "транспорта" не входит контроль правильности данных между системами, что его используют.

но вот внутри в тех частях логика которых фиксирована и не может меняться - вполне подходит массив ключ-значение

Использование KV в контексте DTO/VO - дико хреновая практика, в очень редких кейсах ее использование оправдывает себя. Дело в том, что массив - это набор произвольных данных. Что бы писать надежный код - вам придется на каждом этапе делать проверку правильности этого массива. Что это за проверки?
* все нужные ключи существуют
* все значения по этим ключам правильных типов
* массив не содержит левых данных

как реализовать на php типизированую коллекцию типа как в СИ

class MyTypedCollection implements \Countable, \IteratorAggregate, \ArrayAccess
...
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы