Search
Write a publication
Pull to refresh
8
0
Mike Shapovalov @mike_shapovalov

Software Engineer

Send message

Единственное что я бы изменил это группировку классов в слое. С моей точки зрения удобнее группировать по доменным агрегатам а не по типу классов. Т.е.

domain
  order
    OrderReposityInterface.ts
    Order.ts
    OrderService.ts
    OrderItem.ts


Ну и интерфейс репозитория с моей точки зрения должен объявляться в слое приложения. На моей практике не было не одного случая, когда репозиторий был нужен в слое домена.

Спасибо, очень полезная статья с простыми и понятными примерами, которые можно использовать как вводный материал для разработчиков (причем не только JS), которые ранее не сталкивались с DDD. Добавил в закладки.

Видимо потому что понимаете, что код в вашем подходе будет выглядеть сложнее.

Единственное что я понимаю это то что дискуссия с вами, это пустая трата времени, постараюсь не забыть об этом в следующий раз.

Попробую еще раз объяснить.

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

Я вам уже показывал примеры нормальных доменных объектов с поведением в дискуссиях под другими статьями. Повторять одни и те же аргументы еще раз я не вижу смысла, вы их не слышите. Если вы считаете что наличие класса с конструктором делает ваш код объектно-ориентированным, то у нас с вами представление о ООП очень сильно отличаются, и мы все равно друг друга не поймем.

Понятно, с вашей точки зрения любой код с любыми зависимостями в "доменных сервисах" априори будет более понятен с точки зрения бизнес процесса, чем такой же код внутри сущности. Из опыта предыдущих дискуссий с вами знаю, что никакие аргументы вас не переубедят, поэтому дальнейшую дискуссию считаю бессмысленной.

Мне кажется что мы заходим на очередной круг, когда я вам пытаюсь объяснить преимущество ООП перед процедурным программированием. Мне не удалось это сделать в дискуссиях под другими статьями, видимо не удастся и здесь, Если процедурный подход работает для систем которые вы строите, используйте его дальше. Возможно, когда/если появятся проблемы, вы еще раз посмотрите в сторону ООП и поймете преимущества подхода, когда объект сам контролирует свои инварианты.

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

Но если такой аргумент появится в "доменном сервисе" все сразу станет понятно.

и на производительность 100 лишних ссылок больше влияют, особенно если их инициализировать этими инструментами через рефлексию.

Давайте тогда ORM тоже не использовать, некоторые из них тоже рефлексию используют и ссылки на другие объекты в сущность добавляют

Другому программисту надо разбираться, какая часть кода относится к логике, а какая к деталям реализации.

Ага, не дай бог ещё на функцию которая массив фильтрует, или подстроку находит наткнется в бизнес логике, вконец наверное бедный запутается

Нет, я имел ввиду что в коде доменной области у вас никак не получится избавится от объектов, которые не имеют непосредственного отражения в предметной области, и ваш "доменный сервис" ничуть не лучше "репозитория" либо любой другой "Pure Fabrication" которая облегчает имплементацию доменной логики.

Вы не поверите, но для решения этой проблемы тоже придумали "самообман" https://en.wikipedia.org/wiki/GRASP_(object-oriented_design)#Pure_fabrication

И между прочим ваши доменные сервисы и есть одной из реализаций этого паттерна :)

Потому что доменный сервис обычно создается на старте приложения и существует в одном экземпляре, а сущность создается в середине выполнения запроса по данным из базы, и количество экземпляров может быть хоть 100 штук. Пробросить зависимость в сервис легко, а в сущность нет.

При наличии соответствующих инструментов никакой разницы вообще нет.

Поэтому если мы хотим создать правильную модель описанной логики, в коде метода с реализацией этой логики должны быть переменные "order" и "product", а не "this".

Угу, в доменных сервисах у вас по видимому приватных методов с this тоже нет :)

Я не понимаю как инверсия зависимостей между слоями противоречит теории DDD. И чем внедрение зависимости в сервис лучше внедрения зависимости в агрегат. Напротив, в таком подходе я вижу одни недостатки: либо мы скатывается к анемичной модели и процедурному программированию, либо наш алгоритм размазывается по двум классам, что затрудняет его понимание, поддержку и тестирование.

С моей токи зрения алгоритм который требует внешних данных также должен быть реализован внутри агрегата. В сервисе нужно реализовывать только тот алгоритм который изменяет состояние нескольких агрегатов одновременно, да и в этом случае можно обойтись без сервиса, хотя это будет значительно сложнее. Единственным ограничением реализации алгоритма внутри агрегата является то, что такой алгоритм может только получать данные из внешних источников, но не изменять их состояние. Изменять агрегат может только свое состояние.

Авторы DDD говорят о том что доменный слой не может напрямую зависеть от слоя инфраструктуры. И сервис и агрегат находятся в слое домена. Но вы почему-то допускаете внедрение зависимости в один из компонентов слоя, но не допускаете в другой.

Он и не будет зависеть от инфраструктуры, это инфраструктура будет зависеть от него, для этого и придуман принцип Dependency inversion

Мне не совсем понятно почему внешнюю зависимость нельзя внедрить в агрегат, но можно внедрить в доменный сервис, который находиться в том же слое. Вместо этого предлагается откатится к анемичной модели т.е. де факто к процедурному программированию, потеряв при этом все преимущества ООП.

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

У этого "самообмана" даже официальное название есть Dependency inversion principle :)

https://en.m.wikipedia.org/wiki/Dependency_inversion_principle

Можно эту зависимость инвертировать, вот тут описан подход который мы используем https://habr.com/ru/articles/799019/

Бизнес-сущности ничего не умеют делать и ничего не знают. Они полностью беспомощны. Они просто существуют, и всё. Их единственная задача — наполнять своим существованием предметную область приложения.

Как мы выяснили ранее, бизнес-сущности сами по себе ничего не умеют. Умения бизнес-сущностей сконцентрированы в сервисах.

Вы описали антипаттерн который противоречит основным принципам ООП и тактическим паттернам DDD описанных в книгах Еванса и Вернона. У Мартина Фаулера есть даже отдельная статья на эту тему

Вот цитата из этой статьи:

In general, the more behavior you find in the services, the more likely you are to be robbing yourself of the benefits of a domain model. If all your logic is in services, you've robbed yourself blind.

Полностью можно ознакомиться тут:

https://martinfowler.com/bliki/AnemicDomainModel.html

Доменный слой не знает как и откуда грузятся данные, он только определяет интерфейс получения, и формат данных которые ему нужны для принятия бизнес решения. Непосредственно получением занимается инфраструктура, так что границы ответственности слоев в данном подходе соблюдены.

Information

Rating
Does not participate
Location
Warszawa, Mazowieckie, Польша
Date of birth
Registered
Activity