DDD: Как правильно работать с контекстами ?

camohob

Новичок
А можно какие-то реальные примеры из вашего домена, происходящие с отелем, помимо «добавить», «посмотреть», «удалить»? Потому что здесь не нужен никакой DDD, если всё сводится к этому.
с самим то отелем не много логики... но с отелями заключаются контракты, в которых есть тарифы(даты, цены на различные варианты размещений), доплаты, стопы, квоты, штрафные политики и куча всего всего...
на основе этих данных мы готовим предложения(при любых изменениях предложения готовятся заново)
Потом эти предложения выпадают в поиске..

вот схема... грубо поделена на субдомены, контексты.

 

fixxxer

К.О.
Партнер клуба
Вот, именно к ручному датамаперу мы и пришли. Попробовали сделать конвертацию сущностей доктрины в доменные модели и агрегаты прямо в репозитории - ничего хорошего не вышло... ((
В таком случае вы фактически просто реализуете свой собственный DM вместо Доктрины.

Неужели у всех просто доменная модель мапится в доктрину и всё ?!?!
Ну вообще датамаппер для того и нужен, чтобы не думать о персистенции больше, чем оно того заслуживает. $em->persist($aggregateRoot) и всё.

Я делаю по-разному, не всегда DDD нужен. Но когда делаю по DDD - да, вроде того. Правда, у меня мой форк analogue вместо Доктрины, но суть от этого не меняется.

Да, сам файл в свойстве(по факту это конечно же ссылка на "ленивый" объект). Почему так?
Потому что мы программисты и мыслим алгоритмами и структурами, а не бизнес-сущностями. ;)
На самом деле ничего ужасного в некотором eventual consistency нет. Мне в этом смысле было сложно через себя перешагнуть, "как же так, все связанное должно быть в одной транзакции, делать иначе - это же неправильно" - на самом деле в реальности никаких проблем это не создаёт.
 

camohob

Новичок
Вопрос то собственно был о контекстах, в пределах разных контекстов могут быть модели с различным поведением. А могут одни и те же модели использоваться разными контекстами.
- Квоты могут меняться как из контрактной части(менеджером), так и из заказной(при бронировании или отмене). Поведение при изменении квот может отличаться в зависимости от контекста. Как в таком случае быть?
- Модели некоторых словарей, например страны, города - могут использоваться везде, они и поведения то особого не имеют.

Как вообще в реализации должны выглядеть субдомены, контексты? Нэймспейсы, бандлы?
Как обращаться из одного в другой? Как использовать и где хранить общие модели и сервисы?
 

fixxxer

К.О.
Партнер клуба
Если одни и те же модели используются разными контекстами, то у тебя большая проблема.

Представь себе, что каждый контекст у тебя реализован как отдельное приложение-микросервис, они запущены на разных серверах и обмениваются информацией по сети (по http, или через какой-нибудь message queue - не суть).

Есть такая небольшая, но очень полезная книжка - Domain-Driven Design Distilled. Там это хорошо описано. Автор тот же, что и у IDDD (IDDD, я, честно признаюсь, целиком еще не осилил ;)).
 

AmdY

Пью пиво
Команда форума
В разных контекстах обязательно должны быть разные модели.
Товар в контексте склада и магазина сильно отличается, где-то нужна цена и цвет, а где-то габариты, количество так же обычно считается по разному, поэтому и важно их разделять даже если их мэппинг где-то пересекается.

p.s. Для избавления от дублирования мэппинга в доктрине можно заюзать http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/inheritance-mapping.html
 

Вурдалак

Продвинутый новичок
в которых есть тарифы(даты, цены на различные варианты размещений), доплаты, стопы, квоты, штрафные политики и куча всего всего...
То, что «есть» — это не так интересно. Интересно, что «происходит». Глаголы-команды (заключить контракт, отозвать контракт, оштрафовать, etc.) и глаголы-события (контакт заключён, контракт протух, etc.). Потому что данных может быть очень много, но если они опять-таки все сводятся к CRUD, то тут нечего моделировать.

Как пример, отель может сигнализировать о том, что он забит и не готов больше принимать гостей: $hotel->closeForBooking(). Появляется событие HotelWasClosedForBooking, по которому мы отзываем (cancel? withdraw?) предложения: $offer->withdraw(). Появляется событие OfferWasWithdrawn, по которому мы можем сообщить всем пользователям по email, которые были заинтересованы в этом предложении, что всё плохо. Есть также вероятность, что при блокировке бронирования (closeForBooking) мы можем оштрафовать отель, понизив уровень его доверия и т.д. В этом и заключается самый «жир» бизнес-логики, который нужно контролировать. ООП — это не про правильные иерархии структур («неотъемлемое свойство модели и модель без него не является валидной»), а про messaging.

В тему: http://wiki.c2.com/?AlanKayOnMessaging
 
Последнее редактирование:

camohob

Новичок
Если одни и те же модели используются разными контекстами, то у тебя большая проблема.
а как же отношения между контекстами? "Context Mapping" из этой же книги. Например:
A Shared Kernel is often very difficult to conceive in the first place, and difficult to maintain, because you must have open communication between teams and constant agreement on what constitutes the model to be shared.
О чем эти отношения?
Представь себе, что каждый контекст у тебя реализован как отдельное приложение-микросервис
а это уже взаимодействие контекстов, тут понятно вроде, да
 

camohob

Новичок
В разных контекстах обязательно должны быть разные модели.
Товар в контексте склада и магазина сильно отличается, где-то нужна цена и цвет, а где-то габариты, количество так же обычно считается по разному, поэтому и важно их разделять даже если их мэппинг где-то пересекается.

p.s. Для избавления от дублирования мэппинга в доктрине можно заюзать http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/inheritance-mapping.html
Что модели в контекстах отличаются - это тоже прекрасно понятно. Но вот, например мы будем использовать inheritance-mapping superclass, и разные модели в двух контекстах. Контексты разнесем в разные бандлы, в каждом своя инфраструктура. И где тогда будет мэпинг суперкласса, как его использовать? от чего наследовать сами модели?
 

fixxxer

К.О.
Партнер клуба
@camohob, shared kernel - говно. Там вот прямо дальше описаны нормальные способы.
 

camohob

Новичок
@camohob, shared kernel - говно. Там вот прямо дальше описаны нормальные способы.
Да вся эта теория скоро из глаз потечет уже) как реализовать всё это, вот в чем вопрос...
Я уже обчитался о том, что ДДД это не про реализацию и тд. НО всё же надо как-то реализовать и субдомены и контексты и модели
 

fixxxer

К.О.
Партнер клуба
Да вся эта теория скоро из глаз потечет уже)
Мужик пилит ножовкой дерево, мимо проходит другой
- мужик, ты чо, есть же бензопила, с ней быстрее!
- я не умею
- там научиться - час времени
- мне некогда, мне лес валить надо!
как реализовать всё это, вот в чем вопрос...
Так там прямо написано, как реализовать. Если это противоречит существующей архитектуре, это другой вопрос, на эту тему anti-corruption layer смотри.
 

Вурдалак

Продвинутый новичок
С практической точки зрения лучше всего пригласить кого-то, провести своего рода workshop, чтобы прямо показал чо и как на примере вашего кода.

А так нужно понимать, что на живом проекте подобные эксперименты будут дорого стоить, это будет выглядеть нескладно, криво, ритуально. Потом будете материться. Я не раз становился свидетелем псевдо-DDD/OOP. Это полная жопа. Причём заметил странную особенность, что всем очень нравится слово repository, это становится чуть ли не центром архитектуры.
 
  • Like
Реакции: AmdY

camohob

Новичок
С практической точки зрения лучше всего пригласить кого-то, провести своего рода workshop, чтобы прямо показал чо и как на примере вашего кода.

А так нужно понимать, что на живом проекте подобные эксперименты будут дорого стоить, это будет выглядеть нескладно, криво, ритуально. Потом будете материться. Я не раз становился свидетелем псевдо-DDD/OOP. Это полная жопа. Причём заметил странную особенность, что всем очень нравится слово repository, это становится чуть ли не центром архитектуры.
есть такой специалист на примете?
у нас новый код по мотивам рабочего проекта, вот хочется сделать на этот раз всё по фен-шую.
 

fixxxer

К.О.
Партнер клуба
Это полная жопа. Причём заметил странную особенность, что всем очень нравится слово repository, это становится чуть ли не центром архитектуры.
Ха, да, у меня так вышло, когда я в первый раз узнал про DDD. Ну, понятно почему, мышление "от данных в базе" еще пока никуда не делось, вот и выходит такое. Я это, конечно, потом по-нормальному отрефакторил :)
 

camohob

Новичок
Ха, да, у меня так вышло, когда я в первый раз узнал про DDD. Ну, понятно почему, мышление "от данных в базе" еще пока никуда не делось, вот и выходит такое. Я это, конечно, потом по-нормальному отрефакторил :)
А по-нормальному это как?) что со словом repository "не так"?
 

WMix

герр M:)ller
Партнер клуба
с ним все ок, только к домену отношения не имеет в смысле задачи пихать и вытаскивать нет, это издержки
 
Сверху