DDD и сортировки/фильтрации
DDD и сортировки/фильтрации
Привет, форумчанам. С удивлением обнаружим на форуме топики по DDD и решил задать вопрос сюда. Сам ответ так и не могу найти.
Как вывести в таблицу данные, которые относятся к нескольким сущностям в целом понятно. Можно их по отдельности выбернуть и перемаппить. А вот как потом по этой выборке сделать фильтрации или сортировки так, чтобы это было именно в DDD принципах реализовано.
Вот для примера, выводятся у меня дети с именами родителей. Есть у нас сущность "человек". Мы дергаем всех людей-детей, потом по детям дергаем людей-родителей, маппим и выводим. Используем что-то типа
$childredCollection = $this->get('people_repository')->getChildren();
$parentsCollection = $this->get('people_repository')->getByCollection($childredCollection);
ну и потом маппим как-то. А как вот так же понятно и удобно внедрить сюда сортировки/фильтрации?
Как вывести в таблицу данные, которые относятся к нескольким сущностям в целом понятно. Можно их по отдельности выбернуть и перемаппить. А вот как потом по этой выборке сделать фильтрации или сортировки так, чтобы это было именно в DDD принципах реализовано.
Вот для примера, выводятся у меня дети с именами родителей. Есть у нас сущность "человек". Мы дергаем всех людей-детей, потом по детям дергаем людей-родителей, маппим и выводим. Используем что-то типа
$childredCollection = $this->get('people_repository')->getChildren();
$parentsCollection = $this->get('people_repository')->getByCollection($childredCollection);
ну и потом маппим как-то. А как вот так же понятно и удобно внедрить сюда сортировки/фильтрации?
Re: DDD и сортировки/фильтрации
Код: Выделить всё
$list = $this->get('people_view_repository')->getChildrenWithParents($filter, $sort, $offset, $limit);
Re: DDD и сортировки/фильтрации
Идея мне нравится, потому что она дает решение, как делать. Фильтры и сортировки можно запилить вэлью объектами,чтобы это был не просто массив, а опять же объектный подход.
Но все же это уже будет не предметно-ориентированный репозиторий, а чисто технический, стандартный ООП.
Но все же это уже будет не предметно-ориентированный репозиторий, а чисто технический, стандартный ООП.
Re: DDD и сортировки/фильтрации
поясните мысль.shurup312 писал(а):Но все же это уже будет не предметно-ориентированный репозиторий, а чисто технический, стандартный ООП.
Re: DDD и сортировки/фильтрации
Это отдельный view-репозиторий, добавленный чисто для выборок ради вывода на сайте.shurup312 писал(а):Но все же это уже будет не предметно-ориентированный репозиторий, а чисто технический, стандартный ООП.
Re: DDD и сортировки/фильтрации
зачем? почему в рамках одного нельзя все сделать? листинг данных - вполне ddd задача.ElisDN писал(а):Это второй репозиторий, добавленный чисто для выборок ради вывода на сайте.shurup312 писал(а):Но все же это уже будет не предметно-ориентированный репозиторий, а чисто технический, стандартный ООП.
Re: DDD и сортировки/фильтрации
Если на сайте стопицот виджетов и листингов, требующих кучу выборок с разными JOIN-ами, фильтрами и счётчиками, то тяжёлые агрегаты с кучами лишних данных и медленной гидрацией не особо уместны. В таких случаях по мотивам CQRS предпочитаю помимо оригинального медленного доменного репозитория:zelenin писал(а):зачем? почему в рамках одного нельзя все сделать? листинг данных - вполне ddd задача.
Код: Выделить всё
namespace Domain\Repository;
class PostRepository
{
function get($id): Post
function add(Post $post)
function remove(Post $post)
}
Код: Выделить всё
namespace ReadModel;
class PostFetcher
{
function find($id): ?PostDetailView
function countAll()
function getAll($offset, $limit, $sort): PostListView[]
function countPublished()
function getPublished($offset, $limit)
function countForUser($userId)
function getForUser($userId, $offset, $limit)
function countForTag($tagId)
function getForTag($tagId, $offset, $limit)
function getPopular($limit)
function getResent($limit)
}
Последний раз редактировалось ElisDN 2019.03.28, 00:21, всего редактировалось 5 раз.
Re: DDD и сортировки/фильтрации
Ну когда мы говорим про человека как сущность, то все понятно. И репозиторий создается под него. А когда мы говорим про репозиторий под беренокПлюсРодители, то это уже выглядит как костыль. И данный репозиторий будет содержать опять же джоины потом, так что если какая-то сущность будет переноситься на другое хранилище, то придется править два репозитория. Плюс не совсем понятно, в какой сущности этот репозиторий хотя бы примерно отнести, потому что у нас тут все просто, по факту репозиторий все равно про людей. А если будет владелец+авто? там будут фигурировать уже две разные сущности. И репозиторий будет относиться частично к каждой, но по факту сам по себе, уже скорей как сервис вырисовывается, а не как репозиторий.zelenin писал(а):поясните мысль.shurup312 писал(а):Но все же это уже будет не предметно-ориентированный репозиторий, а чисто технический, стандартный ООП.
Следующий момент - опять же, ну сделали мы репозиторий с join'ом, допустим, если у нас это в мускуле. А потом одна из сущностей решила уехать в MongoDB, тогда вообще ступор.
Хотя тут уже может я перегибаю конечно, и можно просто хранить данные нормализованные как чистый источник данных и данные денормализованные для этой конкретной выборки. В принципе тоже как вариант, правда тогда нужно будет для этого доп.средства записи этих самых денормализованных данных внедрять и не допускать их инвалидации.
Re: DDD и сортировки/фильтрации
Ну и кстати посмотрев на репозиторий
namespace ReadModel\Repository;
class PostReadRepository
{
function get($id): PostDetailView
function countAll()
function getAll($offset, $limit, $sort): PostListView[]
function countPublished()
function getPublished($offset, $limit)
function countForUser($userId)
function getForUser($userId, $offset, $limit)
function countForTag($tagId)
function getForTag($tagId, $offset, $limit)
function getPopular($limit)
function getResent($limit)
}
понимаю, что он все равно плохо решает проблему. у нас же могут быть выборки типа первые десять с группировкой по дате в интервале с 1 января по 10ое полько пользователей с именем вася и возрастом 20-34 года. Я не буду пилить метод для конкретно такой выборки. у нас таблица, над ней обычно фильтр, вот в него могут ввести произвольно что угодно
namespace ReadModel\Repository;
class PostReadRepository
{
function get($id): PostDetailView
function countAll()
function getAll($offset, $limit, $sort): PostListView[]
function countPublished()
function getPublished($offset, $limit)
function countForUser($userId)
function getForUser($userId, $offset, $limit)
function countForTag($tagId)
function getForTag($tagId, $offset, $limit)
function getPopular($limit)
function getResent($limit)
}
понимаю, что он все равно плохо решает проблему. у нас же могут быть выборки типа первые десять с группировкой по дате в интервале с 1 января по 10ое полько пользователей с именем вася и возрастом 20-34 года. Я не буду пилить метод для конкретно такой выборки. у нас таблица, над ней обычно фильтр, вот в него могут ввести произвольно что угодно
Re: DDD и сортировки/фильтрации
формируйте QueryObject и под него один универсальный метод - где-то обсуждали.
Re: DDD и сортировки/фильтрации
Для произвольного поиска так и сделайте:
Код: Выделить всё
function getAllByCriteria($criteria, ...)
Re: DDD и сортировки/фильтрации
Да в CQRS вообще рекомендуют ORM не использовать. Лучше всего подойдет SqlDataProvider или AR. Для списков важна скорость. Если нужны проверки по статусам, датам и др, можно их сделать в AR из которых будете показывать. Да, дублирование, но, как говорится, you have to pay somewhere. Оно не будет сильно страшным. Я считаю, что DDD это не про чтение, это про запись. Не надо делать списки используя DDD в уii - потеряете все DataProvider и Pagination, да и в других fw тоже не стоит.
Re: DDD и сортировки/фильтрации
а тут про орм речь-то и не идет.
yii-шный? да тут и про yii речь не идет.
ar - паттерн орм.
ну ddd действительно скорее про запись, чем про чтение, но тема-то о другом: как гибко создать read-репозитории.anton_z писал(а): ↑2017.01.15, 15:39Для списков важна скорость. Если нужны проверки по статусам, датам и др, можно их сделать в AR из которых будете показывать. Да, дублирование, но, как говорится, you have to pay somewhere. Оно не будет сильно страшным. Я считаю, что DDD это не про чтение, это про запись. Не надо делать списки используя DDD в уii - потеряете все DataProvider и Pagination, да и в других fw тоже не стоит.
Re: DDD и сортировки/фильтрации
А, ну я неверно выразился, прошу прощения. Попробую уточнить.
Думается мне, что само создание read-репозиториев дело не благодарное и не эффективное для сортировки/фильтрации. Что возвращать из этих репозиториев? Сущности? Их же создать, данными заполнить. Здесь нет сложности, управлять которой призвано DDD.
Думается мне, что само создание read-репозиториев дело не благодарное и не эффективное для сортировки/фильтрации. Что возвращать из этих репозиториев? Сущности? Их же создать, данными заполнить. Здесь нет сложности, управлять которой призвано DDD.
Последний раз редактировалось anton_z 2017.01.15, 17:32, всего редактировалось 1 раз.