Здравствуйте, takTak, Вы писали:
T>ок, обратно к нашим баранам,
T>получается, что для калькуляции цен на лету нужна совокупная информация: товарная группа, сам товар (если наценка -скидка только на него), покупатель (с каким-то статусом или без оного), продавец, вот вроде и всё,
Ну, вроде бы да.
T>получается, что наш "заказ" содержит в себе проекции этих перечисленных сущностей с необходимыми нам атрибутами,
T>теперь по поводу реализации: мне лично нравится идея с формулировкой правил подсчёта цены в виде fluent api, что то типа такого https://github.com/NRules/NRules/wiki/Getting-Started, https://stackoverflow.com/questions/42529694/how-to-implement-specification-pattern
T>т.е. "заказ" после инициализации может отсканировать имеющиеся в системе спецификации и применить к себе подходящие, на выходе получаем цену, как такая идея?
В целом неплохо. Но интересны детали. Пример этого fluent api крайне далёк от моего понимания — либо там очень хитрая инверсная семантика, либо он нежизнеспособен.
Типа запустили правило, оно там что-то просканировало, что-то изменило, кого-то оповестило. Кастомер давно свой заказ оплатил и получил — зачем ему эта нотификация?
Наверное, там просто пример и описание решительно невнятное. Потому что сходу неясно, почему нельзя было просто написать всё то же самое на linq2objects и не изобретать горы велосипедов.
var ordersToDiscount = from c in Customers
from o in Orders
where c.IsPreferred && o.Customer = c && o.IsOpen() && !o.IsDiscounted()
select o;
ordersToDiscount.Set(o=>o.PercentDiscount, 10.0);
Если я правильно понял, то у нас будет какой-то метод у класса Order, который наш агрегат. Можете набросать примерную сигнатуру и устройство этого метода?
T>да, динамики нет, если вдруг нужно формулировать новое правило для надценки, то придётся ручками писать новую спецификацию
Ну, совсем без ручной работы не получится — вопрос в изоляции изменений.
T>я не совсем понял роль того, кто может применить к заказу произвольную скидку, это тоже надо как-то учитывать, но по идее, будет какое-то пользовательское действие\событие, на него надо будет реагировать
Вот то-то и оно, что DDD провоцирует думать в неверном направлении. Какие события? Какие действия?
"Действий" у нас, по большому счёту, два с половиной:
1. Рассчитать предполагаемую отпускную цену для каждой позиции. (Показываем проект заказа в UI)
2. Сохранить заказ с заданными отпускными ценами
И ещё пол-сценария: если пользователь имеет уровень менеджера, то мы предлагаем ему возможность скорректировать цены между п.1 и п.2 вручную. Всё.
Никаких "событий", никаких "циклов в поисках кастомеров". Все эти циклы и прочие fluent прекрасны тогда, когда у нас есть система уравнений, и мы её решаем в удобном для нас порядке. В реальной системе основные события порождаются пользователями, ну и плюс асинхронными системами. Вот эта вот идея про "запихать в доменную модель всех покупателей и их заказы и запустить все правила" — как она бы реализовалась, скажем, у Амазона?