
Dmitry
26.09.2018
14:22:05
мм… а разве уровень домена и доменные штуки — это разные вещи?

Adel
26.09.2018
14:22:34
я говорил "приложение" имея ввиду весь код приложения. а не какой-то слой

Aleh
26.09.2018
14:23:03
уровни, слои это все обманы. Есть объекты, модули и связи между ними
их циклы изменения

Google

Aleh
26.09.2018
14:23:16
а загоны по слоям дают больше проблем чем пользы

Adel
26.09.2018
14:24:13
ну... слои дают некоторые правильные понятия ящитаю... но согласен что некоторый народ слишком по ним упарывается и теряет суть

Dmitry
26.09.2018
14:24:41

Adel
26.09.2018
14:24:56
это какие-то технические детали твоей самописной ORM

Dmitry
26.09.2018
14:25:36
так она не моя самописная, а обычный хибернейт

Adel
26.09.2018
14:25:42
они не должны вылезти из папки vendor
аа. так у тебя Ява?
а хибернейт же просто создает все как надо? или ты из того что он создал лепишь уже своё?

Dmitry
26.09.2018
14:27:48
чтобы он работал ему нужно подсунуть размеченные аннотациями классы, в которых аннотациями же «проставлены» связи между классами по полям и типы этих связей.
вот в это дерево классов он потом по запросу и заливает данные. из него же и сохраняет

Adel
26.09.2018
14:28:01
угу
и ты эти классы называешь моделями базы?

Dmitry
26.09.2018
14:28:19
вот это дерево классов я называю моделями, да

Google

Adel
26.09.2018
14:28:25
и потом из них уже лепишь доменные обьекты?

Aleh
26.09.2018
14:28:34
не надо так

Adel
26.09.2018
14:28:42
однако ты очень любишь тратить кучу времени на бесполезный труд.

Dmitry
26.09.2018
14:29:01
лепил. получалось, что DO очень похожи на модели и была куча лишних мапперов
после того как перестал, у меня образовались в этих моделях поля, которые нужны в рантайме и не нужны в базе. отсюда и пошёл дискас

Adel
26.09.2018
14:31:52

Dmitry
26.09.2018
14:34:46
корни агрегатов, сущности и vo это доменные штуки
корень лежит в доменных штуках
модельки базы — в базовых штуках
там же лежит моделька, которая повторяет структуру агрегата
вот как обычно соотносится эта моделька корня и сам корень?
экземпляр модели лежит в поле корня агрегата?
или корень является потомком этой модельки?

Adel
26.09.2018
14:36:25
ну тебе уже говорили про риски. что если упадет то состояние не сохранится и вероятно нужны саги какие-то.

Dmitry
26.09.2018
14:37:06
мне не нужно сохранять именно это состояние. когда всё поднимется состояние прилетит с активных клиентов

Aleh
26.09.2018
14:37:32
так зачем это в агрегате?

Dmitry
26.09.2018
14:38:13
незачем. будет лежать в бизнес-логике или каком-нибудь доменном объекте
это два разных вопроса
в агрегате я хочу хранить состояние шагов (без полей, которые нужны в рантайме) и я не понимаю как красивее связать корень агрегата с моделями базы данных в которых он будет хранить нужное состояние
не на эвентах же это делать

Aleh
26.09.2018
14:56:42
Забыть про модели базы данных
И не придется связывать

Dmitry
26.09.2018
14:57:05
и вот если разделять поля которые нужны в рантайме и поля, которые не нужны.
если всё хранить в одном месте, то получается простая работа с DTO. Спросил у агрегата состояние, смаппил в DTO и отдал на фронт, а потом эвентами менять состояние фронта при смене состояния агрегата.
если же хратить в разных местах — придётся запрашивать состояние из двух мест и в двух местах райзить эвенты для обновления фронта
И не придется связывать
так. а как тогда сохранять стейт агрегата?
забываю про модели => забываю про орм => базы нет => ничего нет.

Aleh
26.09.2018
14:59:07
Корень агрегата мапится в базу, конец истории

Dmitry
26.09.2018
15:05:14
а что значит «маппится в базу» в моём случае с орм?
корень агрегата == модель базы + логика поддержания консистентности ¹
корень агрегата с помощью маппера маппит свой стейт на модели базы ²

Yury
26.09.2018
15:30:20

Google

Dmitry
26.09.2018
15:32:15

Yury
26.09.2018
15:55:50


Роман
26.09.2018
16:15:04
Предположим есть примерно такая задача:
Есть некая подсистема которая производит некий выстрел в пространстве. В ответ она возвращает информацию о том, куда попал выстрел: либо это выстрел по мишени, либо по некоторому объекту окружения. Ещё выстрел мог никуда не попасть.
Суть текущей реализации:
Есть тип Hit. От него два производных типа: TargetHit и EnviromentHit. Все три типа не содержат методов и состоят только из полей.
Есть такая абстракция
public interface IShootBroadcaster
{
Hit Shoot(Shoot shoot);
}
Т.е мы полностью скрываем то, как там высчитываются попадания и в ответ только получаем попадание определённого типа. Далее в зависимости от типа, происходят различные действия. При попадание в цель, высчитываются очки, пишутся логи и прочее. В случае с окружением происходит другой не связный набор действий.
var hit = _shootBroadcaster.Shoot(shoot);
if(hit is EnviromentHit)
{
OnHitEnviroment?.Invoke((EnviromentHit)hit);
}
else if(hit is TargetHit)
{
OnHitTarget?.Invoke((TargetHit)hit);
}
На сколько это адекватно? Классическая реализация паттерна Визитор тут не подойдёт по ряду причин. Я тут вижу только один аналогичный путь - изменить абстракцию. Но на ум ничего лучше не приходит.
Сейчас по сути хрупкое место сосредоточено в том месте, где действие над типом делегируется другой системе (сейчас это выражено через события). Вопрос: как можно побороть это?
Извините что влез в оживлённый спор


Dmitry
26.09.2018
16:18:13


Yury
26.09.2018
16:29:33
"и вот про Rich/Anemic. Хибернейт разве не подталкивает к использованию Rich моделей?"
Думаю он ни к какой модели не подталкивает.
Дублирования тут нет, тк две сущности отвечают за разные контексты. Доменную область и хранение в базе. Если вам нужно будет поменять название поля в базе, то вы поменяете его в сущности персистенса.
В целом можно забить на это и работать в смежной сущности. Доменная сущность и hibernate entity в одном объекте. Это экономит время.


Adel
26.09.2018
16:36:32


Роман
26.09.2018
16:36:58

Adel
26.09.2018
16:37:25
ударение у меня было на слово полиморфизм ?

Роман
26.09.2018
16:37:42
Я вас не понимаю

Adel
26.09.2018
16:37:56
а что такое полиморфизм понимаем?

Роман
26.09.2018
16:38:20
Да

Adel
26.09.2018
16:40:26
я б вообще эвент генерил. и обрабатывал каждый по своему
в принципе у тебя также... почти
в системе произошел выстрел. и она генерит эвент. либо попавший выстрел. либо непопавший.

Google

Adel
26.09.2018
16:42:12
а дальше идет реакция на этот эвент. на каждый разная.

Роман
26.09.2018
16:42:32
И в чём разница?
Если более чётко выделить проблематику: мы не можем делегировать тому во что попали полную обработку попадания
Я помню у Теплякова в книге похожая ситуация разбиралась на примере логгера и разных событий лога
Но всё целиком вспомнить не могу, и видимо лучше перечитать

Dmitry
26.09.2018
16:47:51


Yury
26.09.2018
16:55:13

Dmitry
26.09.2018
17:05:28


Yury
26.09.2018
17:07:52
ок, спасибо, чуть прояснилось. я почему-то не подумал, что так можно было (смешать DO и Persistence)
получается а-ля active-record объект. который и доменный, и немного отвечает за своё сохранение
я просто уточнял, не совсем ли глупость творю
с агрегатом стало понятно — если он лежит в persistence слое, то энтити может быть корнем агрегата и отдельная сущность не нужна.
«проблема» осталась одна — «лишние» поля в энтити. но, наверное, с этим можно смириться.
"«проблема» осталась одна — «лишние» поля в энтити. но, наверное, с этим можно смириться."
- а разве те поля которые не аннотированы - они как и не сохраняются?


Dmitry
26.09.2018
17:09:24
Вот это поясни детальнее, почему это не мапится автоматом?
насколько я понял, мапстракт мапит один объект на другой по заданным правилам.
но когда он маппит A на A' он не знает, что у A есть родительский элемент B на смапленный экземпляр которого нужно тоже поставить ссылку. т.е. в A' должна быть ссылка на B' которая автоматом не делается.
и проще всего её сделать на этапе афтемаппинга B', когда все A' уже смаппились и можно в них проставить ссылки на B'

Aleh
26.09.2018
17:09:28
вы все-таки погрязли в слоях, забудьте про базу и смоделируйте объекты, который пусть просто лежат в памяти
никакого персиста, просто объекты с поведением
после этого надо поверх навесить персист, который будет жить в конфигурациях и новых реализациях репозитория

Yury
26.09.2018
17:11:20
Перейдите на другую маппинг либу где поддержка маппинга связей есть.

Dmitry
26.09.2018
17:12:01

Google

knopkod4v
26.09.2018
17:13:16

Dmitry
26.09.2018
17:18:38

Aleh
26.09.2018
17:18:57
конфигурации маппера
entity это и есть DO
вы смоделировали вашу предметную область в объектах, hibernate и ко используются чтобы персистить эти самые объекты без промежуточных прямо в базу
это в целом идея data mapepr

Yury
26.09.2018
17:21:24

Aleh
26.09.2018
17:21:38
это хорошо

Yury
26.09.2018
17:26:54


Роман
26.09.2018
17:28:24

Dmitry
26.09.2018
17:28:29

Aleh
26.09.2018
17:28:56
это уже как удобнее лично вам в проекте управлять конфигами

Dmitry
26.09.2018
17:30:05
спасибо, теперь понял
в принципе, оно так и получилось к текущему моменту.
сейчас вспомнил ещё одно поле, которое не хочу в базу сохранять — список с EventListener'ами.
(хотя, может быть его там тоже не должно быть)

Aleh
26.09.2018
17:34:00
да уж, список eventListener’ов вряд ли походит на информацию предметной области

Yury
26.09.2018
17:44:39

Dmitry
26.09.2018
17:45:07
т.е EventListenerы в DO — не очень красиво?
а как красивее информировать заинтересованные объекты о изменении какого-то DO?
сделать «шину» для сообщений и передавать ссылку на оную в DO и DO будет её дёргать в нужный момент?
или контроль изенения DO лежит за его пределами? бизнес-логика смотрит на результат сеттера и вызывает листенеров, список которых тоже в бизнес-логике лежит?

Роман
26.09.2018
17:45:45
При этом попадание по цели тоже имеет визуализацию. Возможно мне стоит пересмотреть иеерархию классов