Здравствуйте, Poopy Joe, Вы писали:
PJ>Критерий убедительности в студию.
Приведено решение с набросками кода.
PJ>Не понял контекст. Я ничего не говорил про стейт-машину, от слова совсем.

Это я перескакиваю через рассуждение. Весь документооборот можно описать при помощи стейт-машины. В любом магазине или системе заказов есть т.н. workflow — то самое описание состояний заказа, и действий, которые переводят заказ из состояния в состояние. Вы в своей работе Jira используете? Там можно ткнуть в любом артефакте на кнопочку "workflow" и он покажет схему переходов из состояния в состояние.
Можно это описывать машиной состояний. Машина состояний описывает правила перехода между этими состояниями. Например, если мы приделываем к заказу платёж, то
— заказ в состоянии "новый" переходит в состояние "оплаченный",
— заказ в состоянии "отправленный" переходит в состояние "отправленный, оплаченный"
— заказ в состоянии "доставленный" переходит в состояние "доставленный, оплаченный".
Это в случае, если у нас разрешена пост-оплата. В ней заказ в состоянии "собранный" при выполнении операции "передача в доставку" переходит в "отправленный".
А она может быть как разрешена, так и запрещена. Если она запрещена, то операция "передача в доставку" для состояния "собранный" запрещена. Необходимо состояние "собранный, оплаченный".
То, что вы предлагаете, фактически представляет каждое
состояние отдельным типом.
А что, если возможность пост-оплаты не является статической, а вычисляется динамически? Ну, там, кредит лимитом покупателя? Или страной доставки?
Нет, мы, наверное, можем попытаться выразить и это в рамках системы типов; но у меня подозрение, что кончится всё ровно тем, что валидными останутся более-менее все состояния, а правила будут проверяться внутри операций трансформации.
PJ>Ну я бы предположил отправить заказчику. Но это ж твоя задача, тебе должны быть виднее какие еще есть состояния у заказа.
В реальных системах обработки заказов по 10-20 состояний, и они не исчерпывают
возможное множество состояний. Это просто так нарулен конкретный workflow в конкретном магазине.
Завтра придёт новое требование — техник подправит правило в UI, и заказы будут ходить по-новому.
PJ>В моем мире нет заказов, поэтому меня не надо бомбардировать терминами "наложенным платежом", я без понятия в чем там отличие, но в остальном вот так и работает.
Я бы хотел понять, что тут тебе кажется невозможным.
Заказ наложенным платежом — это когда товар отправляется по почте, а покупатель расплачивается при получении. Термин достаточно распространённый.
PJ>Ну покажи ее продолжение.
Я же показал вам 512 типов заказа, сколько ещё нужно?
PJ>Разумеется позволяет, что заставляет тебя думать обратное? 
Отсутствие примера.
PJ>Никак не связаны, обычно. В этом и есть прелесть системы типов. Ты меняешь модель и все места где инвариант не соблюдается рассыпаются при компиляции. Когда ты их приведешь в соотвествие с новой моделью и компилятор будет счастлив, то все просто будет работать. В обратном случае, если где-то что-то забыть, то окажется что належенный платеж, чтобы это не значило, работает с сайд-эффектами.
PJ>Что такое настоящий язык? Я их только по именам знаю. 
Такой, программу на котором можно исполнить.
PJ>Где тут дублирование кода?
Давайте вы напишете код NewOrder, ShippedOrder, PaidOrder, и PaidShippedOrder. А то я решительно не понимаю, что вы имеете в виду. Вот вы написали, что в этих типах будут методы, "которые сохраняют инвариант модели". Поскольку инварианты у PaidOrder и PaidShippedOrder частично совпадают, то я не вижу нормального способа избежать дублирования кода.
PJ>Это не делат каждое его слово истиной. Так-то много кого почитать полезно. Вот тебе посоветовали почитать Влашина, но я не вижу у тебя энтузиазма. 
Кто из них Влашин? Я всё, что мне давали текстового, прочитал. А тратить по 3 часа на просмотр скучных фильмов у меня возможности нет — мне ещё и работать надо.
PJ>На любом статически типизированом. Наиболее лаконично, разумеется, на функциональных языках. Однако прекрасно работает и на c++. Однако, лаконичность и натуральность это только бонус, большой бонус, да. Но, главное тут гарантии корректности.
Ок, жду пример кода на статически типизированном C#. На с++ есть плохо портируемые в другие языки возможности, вроде параметризации шаблонов трейтами.
PJ>Так хотя бы попробуй. Попытки уже и можно обсуждать. Если у тебя все сводится к "это невозможно потому, что Липперт так сказал", ну используй что можешь. Чего тут обсуждать-то?
(facepalm). Я и так использую то, что могу.
PJ>За фанатов не скажу, но по мне все это детали реализации. Изоляция от базы она совершенно натуральна. Модель зависит от себя самой (ну еще может быть shared kernels других BC), BL зависит от модели, AL зависит от BL и модели, Инфраструктура от всего остального, включая базую. Таким образом внедрить зависимость на базу в логику просто физически не получится. Красота.
Дьявол — в деталях.
PJ>Ну, можно конечно и так интепретировать.
Я не думаю, что тут есть понятие "правильно". Важно что ты хочешь добиться. Вот лично я хочу добиться минимального времени отладки. И оно работатет, и не зависит от размера проекта.
Ну, так-то я тоже за минимальное время отладки. Плюс минимальное время на внесение изменений. Плюс без чудовищных провалов производительности.
А то примеры, которые в сети выдают за DDD, запросто оперируют штуками типа "ну, давайте мы тут материализуем весь прайслист да пробежимся по нему линейным поиском". Ну, в отладке-то наверное это ок, а в продакшне мы на каждый PUT-реквест делаем full table scan по потенциально безлимитному списку, а потом бегаем по этим мегабайтам алгоритмом Шлемиеля.
Нет, такой футбол нам не нужен.