Здравствуйте, Shmj, Вы писали:
S>Почему же не тот?
Товар отгружает тот, кто деньги получил
S> Списали с внутреннего счета, оказали услугу.
Не знаю что такое внутренний счет, и при чем тут услуга не понимаю, о товаре же говорили.
S>Сейчас именно коды возврата vs Exception.
S>>>Получается есть таки 2 лагеря? P>>Больше. Но совсем не диаметрально противоположных.
S>А что кроме варианта код возврата vs Exception есть другие варианты?
Есть, варианты совсем без кодов возврата или Exception не возьмусь советовать А вот использование для одних ситуаций исключений, а для других кодов вполне возможно. Нужно ли
Но не строго два лагеря по большей части по другой причине — для разных языков и при использовании разных библиотек возможны разные варианты, записываться в один из лагерей из абстрактных соображений никто не будет.
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Re[5]: Опять про исключения бизнес-процесса (2017 год)
Y>>2) Y>>bool TryTransfer(int toAccount, decimal amount, out TransferValidationResult transferValidationResult);
TG>Те же коды возврата, вид сбоку. С теми же недостатками.
Да. Иногда приходится жертвовать принципами ради практичности.
TG>
TG>X AVOID using out or ref parameters.
AVOID != DO NOT
Не хочу быть неправильно понятым: лично вполне нравятся исключения. Просто они не единственный вариант.
В FDG я вижу некую коллизию: "Не возвращай коды ошибок, используй исключения" и "Не используй исключения для нормального хода выполнения".
Re[5]: Опять про исключения бизнес-процесса (2017 год)
Y>>X DO NOT use exceptions for the normal flow of control, if possible.
S>Дык... в том то и дело -- в нормальном случае операция проходит и вы отгружаете товар. А если перевести средства не удалось, то это не стандартная ситуация.
S>Вот, даже наш местный MVP, спец. по guidelines, рекомендует юзать Exception: http://rsdn.org/forum/philosophy/6951261.1
Согласен, исключения мне нравятся. Но бывают и частные случаи.
S>Получается есть таки 2 лагеря?
Лагерей может быть даже больше, и народ может перебегать из лагеря в лагерь в зависимости от конкретной ситуации.
Y>>Видятся варианты.
Y>>1) Y>>TransferValidationResult ValidateTransfer(int toAccount, decimal amount); Y>>long Transfer(int toAccount, decimal amount); // бросает исключение при неуспехе
S>Если там 0, то вы просто не отобразите кнопку "перевести средства" в GUI.
От отображения кнопки до её нажатия могут пройти часы. Поэтому при совершении операции нелишне её перепроверить.
Y>>2) Y>>bool TryTransfer(int toAccount, decimal amount, out TransferValidationResult transferValidationResult);
S>Вот, никогда не видел ничего подобного. В обычном случае операция проходит, ведь пред. проверки делаются всегда.
Если проверка делается за час до операции, то она может стать неактуальной. Кроме того, при работе с третьесторонними эндпойнтами могут быть сюрпризы, даже когда все предварительные проверки удались. Тут важно смотреть конкретную ситуацию.
Re[3]: Опять про исключения бизнес-процесса (2017 год)
Здравствуйте, Shmj, Вы писали:
S>А подробнее. Вот, открытие несуществующего файла -- нужно выбросить Exception или же вернуть код возврата?
давайте перестанем говорить о "кодах возврата" и заменим это "алгебраическим типом-результатом", 21-й век всё-таки. Т.е. возвращать будем что-то а-ля variant<result, error>. Или в простейшем случае nullable<T>.
S>Почему вы считаете, что перевод средств с пустого счета чем то отличается от открытия несуществующего файла?
я и не считаю. Я считаю что и в том и в том случае исключения не нужны. Тут ниже написали что исключения нельзя проигнорировать. Юмор в том что именно исключения игнорируются чаще чем возвращаемые значения. Только игнорируются не в плане "не обработали", а наоборот, пять лет назад в коде где-то наверху кто-то написал catch(...) который выводит в лог. И всё. И вот уже на код-ревью никто не задаётся вопросом, а почему выбрасываемое исключение никак не обрабатывается, т.к. "оно ловится выше". Ловится то оно ловится, только сделать что-то вразумительное на этом уровне уже нельзя, т.к. контекст утерян. Если же вы попробуете пробрасывать вразумительный контекст, то у вас сильно будет страдать дизайн кода, а точнее связность возрастёт в разы, т.к. вышележащие слои логики внезапно будут завязаны не только на непосредственный нижележащий, но и на все остальные слои пирога. Поэтому в стандартном слоёном дизайне исключения это дичь, которая применима в очень ограниченных сценариях. Ну например в веб-приложении, когда можно любое исключение на самом верхнем уровне перевести в internal sever error, залогировать, и закрыть полностью соединение.
Re[3]: Опять про исключения бизнес-процесса (2017 год)
Здравствуйте, Masterspline, Вы писали:
SK>>Предпочитает проверять условия предварительно.
M>Система распределенная и сильно многопоточная. Вот ты проверил, что денег достаточно, начал транзакцию, а бабла-то уже и нет, да и счет закрыт/заблокирован.
Это ОЧЕНЬ маловероятно. Не представляю себе пользователя у которого с его банковским счетом ПОСТОЯННО происходят какие то такие движения, да еще незаметно для него.
Все проблемы от жадности и глупости
Re[6]: Опять про исключения бизнес-процесса (2017 год)
Здравствуйте, gandjustas, Вы писали:
G>Для начала почитай: G> G> https://www.artlebedev.ru/best/ui/humaneness/ G>
Ну, Лебедев-то, как обычно, чрезмерно категоричен. В ряде случаев "бюрократическая форма поиска" гораздо удобнее и универсальнее.
Сейчас на куче сайтов такой "человеческий" поиск только мешает.
Re: Опять про исключения бизнес-процесса (2017 год)
Здравствуйте, Shmj, Вы писали:
S>Что если денег на счету не достаточно? Выкинуть исключение NotEnoughMoneyException или же обернуть результат в обертку, где будет код возврата (типа успешно -- значит 0, а -100500 -- значит не хватает денег)? S>Как предпочитает делать большинство?
хз. я за возврат одного из двух вариантов: Получилось и НеПолучилось(поПричине)
...coding for chaos...
Re[7]: Опять про исключения бизнес-процесса (2017 год)
Здравствуйте, vmpire, Вы писали:
V>Ну, Лебедев-то, как обычно, чрезмерно категоричен. В ряде случаев "бюрократическая форма поиска" гораздо удобнее и универсальнее. V>Сейчас на куче сайтов такой "человеческий" поиск только мешает.
А пример можно? есть подозрение что там где мешает нужен не поиск, а подбор по параметрам. Это тоже случай когда потеть должна машина, а не человек, но программисты подумали по-другому.
Re[7]: Опять про исключения бизнес-процесса (2017 год)
Здравствуйте, TG, Вы писали:
TG>Под "предварительными проверками" я имею в виду: достаточно ли денег на счете, не заблокирован ли счет и тому подобное. Т.е. все то, что находится "по ту сторону" функции Transfer() и характеризует состояние внешнего ресурса.
Я тоже про них.
Re[3]: Опять про исключения бизнес-процесса (2017 год)
Здравствуйте, Shmj, Вы писали:
S>Вопрос вот в чем: будете ли вы использовать механизм Exception или же вернете код ошибки + доп. инфо?
использорвать Exception,
а анализ вероятной ошибки + доп. инфо — это отдельный дополнительный механизм, который желательно запускать до вызова процедуры.
Re[3]: Опять про исключения бизнес-процесса (2017 год)
GIV>И вот зачем мне, как пользователю, знать какие там у вас ошибки возможны. С моей стороны все ок? Ну и обрабатывайте тогда. Это саппорту надо как можно больше информации.
Вот вчерашний пример — не мог купить штаны в интернет магазине. Упорно ставят деньги в hold, а мне показывают "возникла проблема с обработкой платежа".
После обращения в саппорт оказалось, что проблема — в адресе доставки, он у них shipping policy не проходит.
А я там блин перебираю карточки, paypal, прочее. В итоге у меня сумма покупки захолдилась 5 (!!!) раз.
Вот мне, как пользователю, было бы крайне полезно знать, "какие там ошибки возможны". Например, чтобы понять, что именно нужно исправить.
Но программисты в последние годы страдают манией "пользователь тупой, давайте ему ничего не скажем".
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: Опять про исключения бизнес-процесса (2017 год)
Здравствуйте, Shmj, Вы писали: S>Функция возвращает номер перевода, если успешно. А если не успешно -- возникает исключение.
S>Что если денег на счету не достаточно? Выкинуть исключение NotEnoughMoneyException или же обернуть результат в обертку, где будет код возврата (типа успешно -- значит 0, а -100500 -- значит не хватает денег)?
Вы как-то странно смотрите на вопрос.
Во-первых, пользователь тут ни при чём. Потому что он не вызывает функцию; он пользуется UI. Для того, чтобы написать вменяемый UI, нужны не коды vs исключения, а достаточная информация для принятия решения.
Например, если мы возвращаем -1 (или бросаем пустой MoneyTransferException), то пользователь не может понять, что ему нужно делать:
— в банкомате нет нужной суммы: пойти в другой банкомат
— достигнут дневной лимит операций по карте: взять другую карту
— достгинут поминутный лимит операций по карте: попробовать ещё раз через пять минут
— превышен лимит разовой операции по карте: разбить платёж на более мелкие
— счёт заблокирован: обратиться в банк
А если нужная инфа предоставлена, то вменяемый программист реализует корректный UI независимо от конкретного механизма. Код возврата — тоже подойдёт, если не зацикливаться на скалярах, и возвращать структуру (например, чтобы сказать, когда можно попробовать ещё раз).
Во-вторых, для неинтерактивных сценариев важны не эти несущественные подробности возврата результата, а возможность автоматически анализировать результат:
— является ли он успешным
— если неуспешен, то по чьей вине неуспех? Т.е. имеет ли смысл повторять эту операцию, или там всё фатально.
— если по вине вызываемого, то через сколько можно выполнять повторную попытку?
— можно ли откатить результат назад, если последующие операции сфейлились
Надо понимать, что "бизнес-процесс" — это не одна операция, а потоки операций, которые должны уметь прерываться, продолжаться, и возвращаться в непротиворечивое состояние, даже при сбое в любом из компонентов.
Грубо говоря, неинтересно, как функция Transfer сигнализирует о проблеме. Интересно, что будет, если во время её выполнения
— прервётся связь между сервером и клиентом
— сервер будет аварийно отключён, не успев вернуть результат
— клиент будет аварийно отключён, не успев получить результат
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Опять про исключения бизнес-процесса (2017 год)
Здравствуйте, Shmj, Вы писали: S>И все же, какой вариант вы бы предпочли? Или в одном месте сделаете так, в другом эдак, без всякого порядка?
Если я проектирую какой-то API, то я бы предпочёл быть консистентным. То есть либо везде — возвраты, либо везде — исключения.
Коды возврата — лучше, но они очень требовательны к системе типов. Поэтому в традиционных средах, типа джавы или дотнета, я предпочёл бы исключения, т.к. там с алгебраическими типами плоховато.
Конкретно идея "возвращать -1 вместо идентификатора трансфера" — абсолютное зло, за такое надо карать.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.