Re[18]: DDD для небольших проектов.
От: Poopy Joe Бельгия  
Дата: 21.02.20 17:37
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Кроме Delivered у нас ещё много промежуточных типов.

И что? Это этого количество путей не становится экспотенциальным. Каждый тип выражает некую бизнес-сущеность. Ее можно выразить через типы, можно спагетти-кодом, можно классами но как-то это сделать придеться.

PJ>>Что значит склеил? ShippableOrder их ко-произведение. Я использую логику процесса, как я его понимаю. На мой взгляд готовность к отправке не зависит от статуса оплаты, по твоим объяснениям.

S>Да, не зависит. Но мне непонятно, как вы собираетесь получать из ShippableOrder при помощи одной операции два разных типа — UnpaidShippedOrder и PaidShippedOrder.
Никак это один тип: UnpaidShippedOrder | PaidShippedOrder, или OneOf<UnpaidShippedOrder, PaidShippedOrder>

PJ>>Зачем нужен второй prepareToShip я не представляю, но вполне допускаю, что смысл в этом может быть. Но, в этом случае, хоть с типами, хоть без, у тебя ровно два решения: две функции или две ветки if-else. А как еще?

S>Ну, очень просто. В плюсах это была бы частичная специализация; в C#/Java у нас была бы простая проверка предусловия.
Ну т.е. две функции и if-else. Я ровно это и сказал.

S> Причём, возможно, вообще не выраженного в коде приложения — была бы конфигурация предиката, которую может править администратор вообще без единого запуска компилятора. Кто ж может себе позволить ре-компиляцию и ре-деплоймент каждый раз, как надо изменить одно из правил

Т.е. администратор может изменить правила и отправить себе бесплатно посылку, без постоплаты? Тогда мы о разном говорим.

S>
S>public static void ShipOrder(Order o)
S>{
S>   Assert(ShippingManager.IsShippingAddressValid(o.ShipmentMethod, o.ShippingAddress);
S>   Assert(BillingManager.IsOrderOkForDelivery(o.BillingMethod, o.Customer);
S>   Assert(o.ProcessingStage == ProcessingStage.ReadyForPickup);
S>   var pickupSchedule = ShippingManager.SchedulePickup(o);
S>   OrderManager.SetStage(ProcessingStage.PickupScheduled, pickupSchedule);  
S>}
S>

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

PJ>>Реально заначимый код это sunny day path. Все остальное это бойлерплейт. Удачи с таким кодом.

S>По моему опыту, sunny day path — это 7% кода. Как раз он и есть boilerplate. Всё остальное — это детальные политики того, что делать, когда всё пойдёт не так.

В примере выше у тебя как раз sunny day и есть, с крэшем во всех остальных случаях.

S>Фрод скрининг, пересортица, обработка отказов сети, обработка отказов от партнёров, вот это вот всё. Потому что happy path — в основном один, или два, а способов сломаться — много.


Именно поэтому поддерживать все это в виде "политик" ага спагетти кода — крайне трудоемко и с большим количеством вероятных ошибок. Типы позволяют не пропустить не один из сценариев, сделать правильную декомпозицию и сосредоточится именно на бизнес-процессе.
Все это делается гораздо проще и надежнее. Вот почитай https://fsharpforfunandprofit.com/rop/
Хотя сам термин и как он используется в F# мне, лично, не нравится. Это просто паттерн и не обязательно про ошибки. Ну хоть так...

S> и C# всё отлично откомпилирует, а F# бы дал по рукам?


Единственное место где F# дает по рукам это неявное приведение типов. int и unit это разные типы. В остальном C# позволяет выражать все то же самое, но большим количеством кода.
Если сравнивать типичный C# код, с "правильным" F# кодом, то таки да. Руки отобьет.

PJ>>Смысл моей фразы в том, что все описанное на f# можно сделать и на c#. Я вовсе не призываю тебя писать на c#, если есть возможность писать на f#, это было бы слабоумно. Но такая возможность не всегда доступна.

S>А этот смысл — он чем-то другой, чем "все тьюринг-полные языки функционально эквивалентны"? Ну, т.е. следует ли из того, что всё, описанное на F#, можно сделать и на IL, оправданность применения IL для описания вот этих вот систем зависимых типов?

Писать на IL необходимости нет, писать на C# у многих вынужденная. Зачем сравнивать какие-то нелепости? На RSDN F# считается мертвым языком, а c# вполне себе популярен. Я не уговариваю писать на C#, но пишут.

PJ>>То же самое и в C# или любом другом языке. Либо ты больше используешь компилятор, либо дебаггер. Как-то так...

S>Не вполне понимаю всё же как именно выносить сайд-эффекты на "границы домена".
Как именно, это не про DDD, это просто паттерн IO/Actions.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.