DDD entity хочет конфиг

Adelf

Administrator
Команда форума
А как в идеальных DDD приложениях сущности к инфраструктуре обращаются?
Вот например есть сущность Post. И нам часто в логике надо знать популярная она или нет. зависит это от разных параметров и пороговые значения задают в конфиге.
Соответственно надо
PHP:
class Post
{
    public function popular(): bool {}
}
и там надо лезть в конфиг. но вроде это некрасиво...
хардкодить вместо конфига? денормализировать и вводить специальный флаг popular в базе который будем рассчитывать постоянно?
Магия с виртуальным полем, которое будет подсчитано с помощью конфига?
 
Последнее редактирование:

Adelf

Administrator
Команда форума
Ну я так и подумал. после того примера с радиусом земли захардкоженным... я понял что "в мире DDD" это нормально :)
Но мне эта идея как-то не очень нравится. Параметров много. В конфиге они красиво-аккуратно выглядят. В коде - не очень. С другой стороны - они только в этом методе и нужны. Зачем их тащить в конфиг... А затем, чтобы дать непрограммисту возможность настраивать их! Это ж всяких маркетологов-сеошников пища. Поэтому хардкод - плохой вариант. Сильно увеличивает лаг между идеей сеошника и реализацией.
 

Вурдалак

Продвинутый новичок
Если это динамические данные, то ты можешь их в метод передавать.
 

AnrDaemon

Продвинутый новичок
Ты вопрос неправильно ставишь. Сущность сама не может определить собственную популярность.
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
Если популярность динамическая и зависит от инфраструктуры, то можно передавать какой-нибудь PopularityCalculator в метод. (Не вижу, чем конфиг от базы отличается в этом смысле).
 

jonjonson

Охренеть
А конфиг разве не репозиторий?
Вопрос в том, что он должен вернуть.
 

WMix

герр M:)ller
Партнер клуба
@Adelf, а снаружи не хочешь передать?
PHP:
class Post
{
    public function popular($params): bool {}
}
 

Adelf

Administrator
Команда форума
Вероятно у меня мышление какое-то не такое. Но для меня передача параметров или PopularityCalculator(или Specification) в метод Post:: popular это ересь какая-то. Значит каждый кто захочет у знать о популярности этого поста должен озаботиться тем, чтобы достать этот PopularityCalculator откуда-то. Но это пожалуй всегда так будет. Другое дело, что это кажется чем-то внешним по отношению к посту. PopularCalculator:: isPopular(Post $post) выглядит более естественным. Для меня. Но это же too anemic. табу.
 

Вурдалак

Продвинутый новичок
Что у тебя за бизнес-логика? От чего зависит popular? На что это влияет?
 

AnrDaemon

Продвинутый новичок
каждый кто захочет у знать о популярности этого поста должен озаботиться тем, чтобы достать этот PopularityCalculator откуда-то
Неверно. Если у тебя по бизнес-логике популярность это свойство поста, то она где-то хранится.
А изменять её ты будешь в ограниченном количестве мест. Которое таки имеет представление о том, что у тебя есть популярность и откуда она берётся.
 

WMix

герр M:)ller
Партнер клуба
На самом деле выбор не большой.
1. Посты содержат модификаторы и считают.
- модификаторы заинжектины,
- модификаторы считываются внутри
- модификаторы переданы параметром
2. Популярность возвращает непросчитанный обьект/функцию которую еще придеться набить модификаторами, чтоб получить скалярное значение.
 

fixxxer

К.О.
Партнер клуба
Ну а если так?
PHP:
class PostPopulatiryArguments {
    // немного typescript syntax, потому что мне лень писать
     public __construct(public readonly $commentsCount, public readonly $subscribersCount, public readonly $likesCount); 
}
class Post {
     public getPopularityArguments() : PostPopulatiryArguments { ... }
}
class PostPopularityCalculator {
     public __construct(private $config) {}
     public isPopular(PostPopulatiryArguments $args) : boolean {
         return $args->commentsCount * $this->config->commentsCountFactor + ... >= $this->config->threshold;
     }
}
Ну или денормализация с введением post->isPopular:
PHP:
class Post {
     public defineIsPopularWith(PostPopularityCalculator $calculator) {
          $this->isPopular = $calculator->isPopular(new PostPopularityArguments(...));
     }
}
Тут еще вопрос в том, нужен ли этот флаг isPopular внутри модели Post или нет.
 
Последнее редактирование:

Вурдалак

Продвинутый новичок
Здесь вообще много вопросов возникает. Например: будет ли флаг для денормализации в сущности/таблице, чтобы делать выборку популярных постов? Если будет, то что происходит, если поменяли конфиг? Нужен ли флаг самой сущности? От каких параметров поста будет зависеть популярный ли он?

Мне хоть убей не нравится, когда у сущности какие-то геттеры появляются. Эти замечательные геттеры можно запихнуть с read model и делать с ней всё, что хочется. Более того, в read model даже можно в конструктор передать все вот эти параметры из конфига:
PHP:
namespace Foo\Bar\ReadModels;

final class Post
{
    public function __construct(int $id, ..., float $commentsCountFactor, float $threshold, ...)
    {
        // ...
    }
}
И скорее всего популярность действительно зависит от количества комментариев и прочего, что уже точно не хочется держать в исходной сущности: это мусор для read model.

Я изначально предположил, что у @Adelf есть какая-то логика в самой сущности, но похоже это опять read model. Опять только про отображение.
 
Последнее редактирование:
Сверху