Re[13]: DDD для небольших проектов.
От: Sinclair Россия https://github.com/evilguest/
Дата: 14.02.20 16:10
Оценка:
Здравствуйте, Poopy Joe, Вы писали:

PJ>Тут ровно две степени сводобы оплачен или нет. Все остальные типы завсисимые.

Они были бы зависимыми, если бы мы писали на C++. Там бы мы параметризовали шаблонный тип Order всеми нужными нам аргументами, и безо всяких конструкторов писали бы прямо правила трансформации.
Там да — можно было бы описать, что рефанд реквест возможен только для ордера, у которого проведён платёж, независимо от его остальных компонентов состояния.
А в дотнете вы выписываете все эти типы ордеров руками.

S>>И эта модель у нас теряет информацию: после отправки у нас уже нет никаких данных о том, был ли заказ оплачен. Ну, то есть наверное можно попробовать это починить, добавив в ShippedOrder и DeliveredOrder свойство Order по образцу ShippableOrder. Но не факт, что этого достаточно: если мы хотим потребовать платёж-при-получении от наших Shippable(UnpaidOrder), то как будет выглядеть сигнатура конструктора DeliveredOrder?

PJ>Это все зависит от того как это системой обрабатывается. Можно при создании ShippableOrder создавать еще и PaymentRequest и обрабатывать его отдельно, позваляя, например, переводить деньги на счет. С собственно доставкой эта операция не больно-то связана. Не обязательно все валить в одну кучу.
Ну, с доставкой не связана. И как нам это поможет?

S>>Надо полагать, будет что-то типа

S>>
S>>        public DeliveredOrder(ShippedPaidOrder order){} // тут paymentInfo и так есть
S>>        public DeliveredOrder(ShippedUnpaidOrder order, PaymentInfo paymentInfo){} // а тут надо её предоставить
S>>

S>>Может, я чего-то не понимаю, но у нас только что класс ShippedOrder развалился надвое, чтобы была возможность сделать два разных конструктора для DeliveredOrder.
А заодно придётся развалить пополам и класс ShippableOrder.
PJ>В каком, прости, месте? И в том, и в другом случае ты создаешь тип одын штука.
Как это в каком? Появились типы ShippedPaidOrder и ShippedUnpaidOrder. А как иначе мы выразим требование "заказ перед выдачей должен быть оплачен" при помощи типов?

PJ>Да хоть 110. Ты это говоришь с таким придыханим, как будь-то у тебя количество типов чем-то ограничено.

Отлично. Только что вы не верили, что у нас получится экспоненциальный рост количества классов. А теперь мы от фазы отрицания переходим к фазе гнева, да?
Теперь уже и 110 классов не страшно
PJ>А куда ты поместишь код когда начнешь думать о возвратах? В астрал?
Как куда? В код бизнес-логики. Проверяем предусловия, и поехали. Пишется ровно такой же код "трансформации", только проверки предусловий выполняются прямо по месту действия правила, а не в момент конструирования аргумента.

PJ>Детали реализации. Может да, может нет. Никто не мешает имееть структуру Tuple<ShippedOrder, PaymentRequest> Все эти типы можно как угодно массировать до получения полного удовлетворения и уверенност, что вот сейчас все так как ты и хотел.

Ну вот я и не понимаю, как добиться того, "чего я хотел". Ну сделаю я этот Tuple — дальше-то что?

PJ>Не надо. C# поддерживает nullable reference types.

Вы хотели сказать "non-nullable reference types"? Ну, этой фиче без году неделя, у меня пока нет опыта пользования. В описании авторов это выглядит так, что "ну, мы вроде иногда чего-то там проверяем", поэтому уверенности в железобетонности "скомпилировалось — значит работает" у меня нету.

PJ>Если ты хочешь наехать на бойлерплейт в C#, то есть куда более болезенные места. Например, дефолтный equality comparer, который проверяет ссылку, отсутствие ADT, нормальной композии и убогий паттерн-матчинг.

PJ>Но так все это одинаково справедливо хоть с DDD, хоть без. C# это путь боли. Но это ж добровольный выбор.
Количество бойлерплейта радикально зависит от того, какой стиль кода выбран. Пока что у меня впечатление, что только лишь F# имеет (если имеет) достаточно мощную систему типов, чтобы описывать бизнес-правила с нужной точностью.
Потому что в шарпе мы быстро упираемся в то, что вместо сокращения объёма кода начинаем его увеличивать.
PJ>Следит. Хотя пока в виде варнинга, но варнинги можно и как ошибки поставить.
Надо будет поэкспериментировать.

PJ>Эээ...?! Модель это модель. В DDD есть value objects, то у чего нет ID. Адрес например. Entities — то, у чего есть ID. Иначе говоря разные инстансы могут ссылаться на одну entity. И агрегаты — коллекции entities. В данном пример customer, article это, очевидно, ссылки на них. Так что order это агрегат и есть.

Ок. А бизнес-логика, она в труъ DDD в агрегатах, или ещё где-то?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.