Re: Опять про исключения бизнес-процесса (2017 год)
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.11.17 03:58
Оценка: 7 (2) +5
Здравствуйте, Shmj, Вы писали:

S>Как сейчас, уже пришли к единому мнению по этому вопросу или нет? Ранее было 2 лагеря, первый из которых был "за" (особенно много представителей в Java-среде), второй против. Доходило до мордобоя...


S>Функция возвращает номер перевода, если успешно. А если не успешно -- возникает исключение.

S>Что если денег на счету не достаточно? Выкинуть исключение NotEnoughMoneyException или же обернуть результат в обертку, где будет код возврата (типа успешно -- значит 0, а -100500 -- значит не хватает денег)?

В общем случае ТОЛЬКО исключение. Без вариантов.
Коды ошибок слишком легко проигнорировать.

Например после перевода денег клиенту отправляется товар. Забыли проверить код ошибки — упс, заказчик потерял деньги.

Есть некоторые частные случаи когда можно отойти от этого правила.
Например если перевод денег — конечный результат нужный пользователю. То есть результат будет прямо отображен на экране и не будет больше никак обрабатываться.
Второй пример — "паттерн" TryOperation. Когда положительный и отрицательный результат функции равновероятны и в случае отрицательного результата программа будет делать что-то еще, а не просто прервет операцию. Но даже Try-функции будут кидать исключения в некоторых случаях.
Re: Опять про исключения бизнес-процесса (2017 год)
От: vmpire Россия  
Дата: 31.10.17 10:15
Оценка: +4
Здравствуйте, Shmj, Вы писали:

S>Как сейчас, уже пришли к единому мнению по этому вопросу или нет? Ранее было 2 лагеря, первый из которых был "за" (особенно много представителей в Java-среде), второй против. Доходило до мордобоя...

Не было двух лагерей. Были люди, не изучившие гайдлайны.

S>Как предпочитает делать большинство?

Большинство предпочитает соблюдать гайдлайны: если это ожидаемая ошибка (например, пользовательский ввод) — не использовать исключения, а проверять явно и возвращать код возврата (или как-то ещё сообщать о неудаче).
Если не ожидаемая — кидать исключение и ловить его где-то в точке возможного восстановления. Или даже не ловить вообще, зависит от приложения.
http://www.informit.com/articles/article.aspx?p=2133373&seqNum=6
https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/exception-throwing
Re[2]: Опять про исключения бизнес-процесса (2017 год)
От: Real 3L0 Россия http://prikhodko.blogspot.com
Дата: 31.10.17 06:16
Оценка: +2
Здравствуйте, Stanislaw K, Вы писали:

S>>Как предпочитает делать большинство?

SK>Предпочитает проверять условия предварительно.

В данном примере это не поможет для всех случаев.
Вселенная бесконечна как вширь, так и вглубь.
Re[2]: Опять про исключения бизнес-процесса (2017 год)
От: Masterspline  
Дата: 01.11.17 01:44
Оценка: +2
SK>Предпочитает проверять условия предварительно.

Система распределенная и сильно многопоточная. Вот ты проверил, что денег достаточно, начал транзакцию, а бабла-то уже и нет, да и счет закрыт/заблокирован.
Re[3]: Опять про исключения бизнес-процесса (2017 год)
От: antropolog  
Дата: 01.11.17 08:48
Оценка: +2
Здравствуйте, Shmj, Вы писали:

S>А подробнее. Вот, открытие несуществующего файла -- нужно выбросить Exception или же вернуть код возврата?


давайте перестанем говорить о "кодах возврата" и заменим это "алгебраическим типом-результатом", 21-й век всё-таки. Т.е. возвращать будем что-то а-ля variant<result, error>. Или в простейшем случае nullable<T>.

S>Почему вы считаете, что перевод средств с пустого счета чем то отличается от открытия несуществующего файла?


я и не считаю. Я считаю что и в том и в том случае исключения не нужны. Тут ниже написали что исключения нельзя проигнорировать. Юмор в том что именно исключения игнорируются чаще чем возвращаемые значения. Только игнорируются не в плане "не обработали", а наоборот, пять лет назад в коде где-то наверху кто-то написал catch(...) который выводит в лог. И всё. И вот уже на код-ревью никто не задаётся вопросом, а почему выбрасываемое исключение никак не обрабатывается, т.к. "оно ловится выше". Ловится то оно ловится, только сделать что-то вразумительное на этом уровне уже нельзя, т.к. контекст утерян. Если же вы попробуете пробрасывать вразумительный контекст, то у вас сильно будет страдать дизайн кода, а точнее связность возрастёт в разы, т.к. вышележащие слои логики внезапно будут завязаны не только на непосредственный нижележащий, но и на все остальные слои пирога. Поэтому в стандартном слоёном дизайне исключения это дичь, которая применима в очень ограниченных сценариях. Ну например в веб-приложении, когда можно любое исключение на самом верхнем уровне перевести в internal sever error, залогировать, и закрыть полностью соединение.
Re: Опять про исключения бизнес-процесса (2017 год)
От: Sinclair Россия https://github.com/evilguest/
Дата: 17.11.17 05:13
Оценка: 4 (1)
Здравствуйте, Shmj, Вы писали:
S>Функция возвращает номер перевода, если успешно. А если не успешно -- возникает исключение.

S>Что если денег на счету не достаточно? Выкинуть исключение NotEnoughMoneyException или же обернуть результат в обертку, где будет код возврата (типа успешно -- значит 0, а -100500 -- значит не хватает денег)?

Вы как-то странно смотрите на вопрос.
Во-первых, пользователь тут ни при чём. Потому что он не вызывает функцию; он пользуется UI. Для того, чтобы написать вменяемый UI, нужны не коды vs исключения, а достаточная информация для принятия решения.
Например, если мы возвращаем -1 (или бросаем пустой MoneyTransferException), то пользователь не может понять, что ему нужно делать:
— в банкомате нет нужной суммы: пойти в другой банкомат
— достигнут дневной лимит операций по карте: взять другую карту
— достгинут поминутный лимит операций по карте: попробовать ещё раз через пять минут
— превышен лимит разовой операции по карте: разбить платёж на более мелкие
— счёт заблокирован: обратиться в банк
А если нужная инфа предоставлена, то вменяемый программист реализует корректный UI независимо от конкретного механизма. Код возврата — тоже подойдёт, если не зацикливаться на скалярах, и возвращать структуру (например, чтобы сказать, когда можно попробовать ещё раз).

Во-вторых, для неинтерактивных сценариев важны не эти несущественные подробности возврата результата, а возможность автоматически анализировать результат:
— является ли он успешным
— если неуспешен, то по чьей вине неуспех? Т.е. имеет ли смысл повторять эту операцию, или там всё фатально.
— если по вине вызываемого, то через сколько можно выполнять повторную попытку?
— можно ли откатить результат назад, если последующие операции сфейлились

Надо понимать, что "бизнес-процесс" — это не одна операция, а потоки операций, которые должны уметь прерываться, продолжаться, и возвращаться в непротиворечивое состояние, даже при сбое в любом из компонентов.
Грубо говоря, неинтересно, как функция Transfer сигнализирует о проблеме. Интересно, что будет, если во время её выполнения
— прервётся связь между сервером и клиентом
— сервер будет аварийно отключён, не успев вернуть результат
— клиент будет аварийно отключён, не успев получить результат
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: Опять про исключения бизнес-процесса (2017 год)
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.11.17 05:14
Оценка: 2 (1)
Здравствуйте, TG, Вы писали:

TG>Здравствуйте, gandjustas, Вы писали:


G>>Предварительная проверка нужна независимо от спора коды\исключения.

TG>Где-то на этом форуме уже обсуждали, что попытаться сразу выполнить операцию без предварительных проверок и проще и дешевле. Тем более, что результат такой проверки может стать неактуальным практически мгновенно.


Для начала почитай:
  1. https://www.artlebedev.ru/best/ui/humaneness/
  2. http://bureau.ru/bb/soviet/20150714/
  3. http://medvedism.ru/blog/all/birman-ui-and-datavis-course-1/

Дальше включай мозг.

Вот есть примитивная программа, в ней только номер счета отправителя, номер счета получателя и кнопка "отправить".
И есть два варианта:
1) Проверки делать в момент отправки и в случае чего кидать пользователю ошибку.
2) Проверки делать в момент открытия программы и просто делать кнопку "отправить" неактивной.
В 99% случаев более уместен второй вариант. В этом случае операция не будет выполняться если не выполнены предусловия.

Конечно второй вариант будет для программиста сложнее, но тебе в конце концов платят деньги чтобы ты эти сложности преодолевал.
Конечно во втором варианте результат проверки "практически мгновенно" станет неактуальным. Но ты может также "практически мгновенно" его актуализировать. А учитывая, что перевод денег "практически мгновенно" в реальной жизни не происходит, то вполне можно подобрать достаточный интервал для актуализации.

ЗЫ. Самый дорогой ресурс, который ты можешь сэкономить или потратить — время пользователя. Оно прямо связано с расходами на эксплуатацию и с выручкой, если программа продается.
Re: Опять про исключения бизнес-процесса (2017 год)
От: Stanislaw K СССР  
Дата: 31.10.17 05:51
Оценка: +1
Здравствуйте, Shmj, Вы писали:

S>Функция возвращает номер перевода, если успешно. А если не успешно -- возникает исключение.


S>Что если денег на счету не достаточно? Выкинуть исключение NotEnoughMoneyException или же обернуть результат в обертку, где будет код возврата (типа успешно -- значит 0, а -100500 -- значит не хватает денег)?


Кроме нехватки денег может быть еще два десятка причин для отказа, как то "счет заблокирован", "запрещены транзакции через интернет", "банк получателя недоступен", "счет получателя заблокирован"....

S>Как предпочитает делать большинство?


Предпочитает проверять условия предварительно.
Все проблемы от жадности и глупости
Re[2]: Опять про исключения бизнес-процесса (2017 год)
От: GarryIV  
Дата: 31.10.17 10:18
Оценка: +1
Здравствуйте, sereginseregin, Вы писали:

S>Функция выдаст только название этапа, на котором она споткнулась, так как ограничения в системах (резерв, блокировка счета, технический отказ системы) и сообщения о них для надежности прописываются максимально простым языком. Название этапа не помогает пользователю принять решение. Блокировка счета может быть отменена через секунду после неудачной операции, поэтому пользователю лучше предварительно указать на возможные ошибки с предоставлением максимально подробной информации.


И вот зачем мне, как пользователю, знать какие там у вас ошибки возможны. С моей стороны все ок? Ну и обрабатывайте тогда. Это саппорту надо как можно больше информации.
WBR, Igor Evgrafov
Re[3]: Опять про исключения бизнес-процесса (2017 год)
От: vmpire Россия  
Дата: 31.10.17 11:10
Оценка: +1
Здравствуйте, yenik, Вы писали:

S>>>Как предпочитает делать большинство?

V>>Большинство предпочитает соблюдать гайдлайны: если это ожидаемая ошибка (например, пользовательский ввод) — не использовать исключения, а проверять явно и возвращать код возврата (или как-то ещё сообщать о неудаче).
V>>Если не ожидаемая — кидать исключение и ловить его где-то в точке возможного восстановления. Или даже не ловить вообще, зависит от приложения.

Y>Ответ слишком сферичен в вакууме. Ожидаемая/неожидаемая — это не всегда бинарное состояние. Что если ожидаемая, но очень редкая?

А вот для ответов на такие вопросы и есть системный архитектор или главный программист, который и должен решать, что как для данного конкретного проекта.
Потому, что без знания специфики проекта это всегда будет сферический ответ в вакууме.
Где-то и на ошибки пользователя можно кидать исключения (например, если полноценная проверка была в предыдущем слое приложения).
А где-то и отсутствующий файл конфигурации или деление на ноль приравнивается к ожидаемой ошибке (если, например, это высокоустойчивая система, которая должена работать любой ценой, даже с риском неправильной работы).
Re[2]: Опять про исключения бизнес-процесса (2017 год)
От: Shmj Ниоткуда  
Дата: 31.10.17 23:08
Оценка: +1
Здравствуйте, vmpire, Вы писали:

S>>Как предпочитает делать большинство?

V>Большинство предпочитает соблюдать гайдлайны: если это ожидаемая ошибка (например, пользовательский ввод) — не использовать исключения, а проверять явно и возвращать код возврата (или как-то ещё сообщать о неудаче).

Пользовательский ввод и ожидаемое исключение (как в Java) -- это несколько разное. К примеру при открытии файла FileNotFoundException -- будет ожидаемым, но вы же не станете в этом случае использовать код возврата?

V>Если не ожидаемая — кидать исключение и ловить его где-то в точке возможного восстановления. Или даже не ловить вообще, зависит от приложения.

V>http://www.informit.com/articles/article.aspx?p=2133373&amp;seqNum=6
V>https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/exception-throwing

Давайте ближе к нашему примеру с переводом средств. Вы бы делали NotEnoughMoneyException или код возврата?

В guidelines не вижу нигде совета делать коды возврата для данного сценария, наоборот написано "DO NOT return error codes".

Перевод средств с пустого счета целиком аналогичен открытию несуществующего файла. Если при открытии несуществующего файла принято выбрасывать исключение, то почему при переводе с пустого счета нужно поступать иначе?
Re[4]: Опять про исключения бизнес-процесса (2017 год)
От: TG  
Дата: 01.11.17 07:02
Оценка: +1
Здравствуйте, sereginseregin, Вы писали:

S>Речь о том, что функция вернет только краткую техническую информацию, расшифровывать ее все равно придется, поэтому нет смысла заморачиваться со сложными исключениями


Смысл заморачиваться с исключениями в том, что их не проигноришь.

Есть, конечно, вариант, что кто-нибудь напишет пустой catch, но это на порядок проще обнаружить, чем необработанный код возврата.
Re[3]: Опять про исключения бизнес-процесса (2017 год)
От: Sinclair Россия https://github.com/evilguest/
Дата: 17.11.17 05:02
Оценка: +1
GIV>И вот зачем мне, как пользователю, знать какие там у вас ошибки возможны. С моей стороны все ок? Ну и обрабатывайте тогда. Это саппорту надо как можно больше информации.
Вот вчерашний пример — не мог купить штаны в интернет магазине. Упорно ставят деньги в hold, а мне показывают "возникла проблема с обработкой платежа".
После обращения в саппорт оказалось, что проблема — в адресе доставки, он у них shipping policy не проходит.
А я там блин перебираю карточки, paypal, прочее. В итоге у меня сумма покупки захолдилась 5 (!!!) раз.
Вот мне, как пользователю, было бы крайне полезно знать, "какие там ошибки возможны". Например, чтобы понять, что именно нужно исправить.
Но программисты в последние годы страдают манией "пользователь тупой, давайте ему ничего не скажем".
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Опять про исключения бизнес-процесса (2017 год)
От: Shmj Ниоткуда  
Дата: 30.10.17 22:59
Оценка:
Как сейчас, уже пришли к единому мнению по этому вопросу или нет? Ранее было 2 лагеря, первый из которых был "за" (особенно много представителей в Java-среде), второй против. Доходило до мордобоя...

Классический пример, фукнция перевода денег на счет:

long Transfer(int toAccount, decimal amount);


Функция возвращает номер перевода, если успешно. А если не успешно -- возникает исключение.

Что если денег на счету не достаточно? Выкинуть исключение NotEnoughMoneyException или же обернуть результат в обертку, где будет код возврата (типа успешно -- значит 0, а -100500 -- значит не хватает денег)?

Как предпочитает делать большинство?
Re: Опять про исключения бизнес-процесса (2017 год)
От: Real 3L0 Россия http://prikhodko.blogspot.com
Дата: 31.10.17 06:17
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Как предпочитает делать большинство?


Я предпочитаю делить ошибки на "бизнес" и "системные". В твоём примере — это бизнес ошибки, которые должен обрабатывать пользователь программы.
Вселенная бесконечна как вширь, так и вглубь.
Re: Опять про исключения бизнес-процесса (2017 год)
От: sereginseregin Россия http://daremanager.sourceforge.net/ru/
Дата: 31.10.17 06:48
Оценка:
Функция выдаст только название этапа, на котором она споткнулась, так как ограничения в системах (резерв, блокировка счета, технический отказ системы) и сообщения о них для надежности прописываются максимально простым языком. Название этапа не помогает пользователю принять решение. Блокировка счета может быть отменена через секунду после неудачной операции, поэтому пользователю лучше предварительно указать на возможные ошибки с предоставлением максимально подробной информации.
Re: Опять про исключения бизнес-процесса (2017 год)
От: Qulac Россия  
Дата: 31.10.17 10:42
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Как сейчас, уже пришли к единому мнению по этому вопросу или нет? Ранее было 2 лагеря, первый из которых был "за" (особенно много представителей в Java-среде), второй против. Доходило до мордобоя...


S>Классический пример, фукнция перевода денег на счет:


S>
S>long Transfer(int toAccount, decimal amount);
S>


S>Функция возвращает номер перевода, если успешно. А если не успешно -- возникает исключение.


S>Что если денег на счету не достаточно? Выкинуть исключение NotEnoughMoneyException или же обернуть результат в обертку, где будет код возврата (типа успешно -- значит 0, а -100500 -- значит не хватает денег)?


S>Как предпочитает делать большинство?


Перевод денег это довольно долгая операция поэтому лучше возвращать результат в виде объекта представляющего перевод. В одних случаях мы бросаем исключение(нет денег на счете, счет заблокирован), в других информацию об ошибке клиент получает проверяя статус объекта представляющего перевод денег.
Программа – это мысли спрессованные в код
Re[2]: Опять про исключения бизнес-процесса (2017 год)
От: yenik  
Дата: 31.10.17 10:43
Оценка:
S>>Как предпочитает делать большинство?
V>Большинство предпочитает соблюдать гайдлайны: если это ожидаемая ошибка (например, пользовательский ввод) — не использовать исключения, а проверять явно и возвращать код возврата (или как-то ещё сообщать о неудаче).
V>Если не ожидаемая — кидать исключение и ловить его где-то в точке возможного восстановления. Или даже не ловить вообще, зависит от приложения.

Ответ слишком сферичен в вакууме. Ожидаемая/неожидаемая — это не всегда бинарное состояние. Что если ожидаемая, но очень редкая?
Re[4]: Опять про исключения бизнес-процесса (2017 год)
От: yenik  
Дата: 31.10.17 11:13
Оценка:
Y>>Ответ слишком сферичен в вакууме. Ожидаемая/неожидаемая — это не всегда бинарное состояние. Что если ожидаемая, но очень редкая?
V>А вот для ответов на такие вопросы и есть системный архитектор или главный программист, который и должен решать, что как для данного конкретного проекта.

Это верно. В сущности, сферичен сам вопрос в стартовом сообщении. Тут следовало бы начать с выяснения особенностей реализуемой системы.
Re: Опять про исключения бизнес-процесса (2017 год)
От: antropolog  
Дата: 31.10.17 13:08
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Как предпочитает делать большинство?


в подавляющем большинстве случаев использование исключений это ошибка дизайна.
Re[3]: Опять про исключения бизнес-процесса (2017 год)
От: sereginseregin Россия http://daremanager.sourceforge.net/ru/
Дата: 31.10.17 13:23
Оценка:
Здравствуйте, GarryIV, Вы писали:

GIV>И вот зачем мне, как пользователю, знать какие там у вас ошибки возможны. С моей стороны все ок? Ну и обрабатывайте тогда. Это саппорту надо как можно больше информации.


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

Речь о том, что функция вернет только краткую техническую информацию, расшифровывать ее все равно придется, поэтому нет смысла заморачиваться со сложными исключениями
Re: Опять про исключения бизнес-процесса (2017 год)
От: scf  
Дата: 31.10.17 14:18
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Как сейчас, уже пришли к единому мнению по этому вопросу или нет? Ранее было 2 лагеря, первый из которых был "за" (особенно много представителей в Java-среде), второй против. Доходило до мордобоя...


В настоящее время мнение склоняется к "коды ошибок", но активно использются оба подхода.
Либо иерархия исключений, либо sealed hierarchy объектов ошибок, когда компилятор может проверить, что все случаи обработаны.

Всё зависит от стратегии обработки ошибок в программе.

Зависит ли обработка ошибок от типа ошибки? в веб-приложении часто достаточно сказать "500" и записать стектрейс в лог, а где-то все возможные ошибки нужно тщательно обработать. Часто использутся промежуточный вариант, тогда очень важно правильно классифицировать ошибки. Воспроизводимые/случайные. Пользовательские/системные. Известные/неизвестные.

Где обрабатываются ошибки? В месте возникновения или на самом верху?

Должна ли ошибка содержать структурированную информацию о контексте?

И т.п.
Отредактировано 31.10.2017 14:19 scf . Предыдущая версия .
Re[2]: Опять про исключения бизнес-процесса (2017 год)
От: Shmj Ниоткуда  
Дата: 31.10.17 16:22
Оценка:
Здравствуйте, Stanislaw K, Вы писали:

SK>Предпочитает проверять условия предварительно.


Что значит предварительно? Вы проверили, денги были. Пока вызвали -- денег уже нет.
Re: Опять про исключения бизнес-процесса (2017 год)
От: Буравчик Россия  
Дата: 31.10.17 20:54
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Что если денег на счету не достаточно? Выкинуть исключение NotEnoughMoneyException или же обернуть результат в обертку, где будет код возврата (типа успешно -- значит 0, а -100500 -- значит не хватает денег)?


S>Как предпочитает делать большинство?


Сгенерировать TransferException, внутри которого поле "причина" равна -100500, что означает "не хватает денег"
Best regards, Буравчик
Re[2]: Опять про исключения бизнес-процесса (2017 год)
От: Shmj Ниоткуда  
Дата: 31.10.17 22:59
Оценка:
Здравствуйте, Real 3L0, Вы писали:

S>>Как предпочитает делать большинство?


R3>Я предпочитаю делить ошибки на "бизнес" и "системные". В твоём примере — это бизнес ошибки, которые должен обрабатывать пользователь программы.


А как функция сообщит пользователю что ошибка? Вернет код ошибки или сгенерит исключение?
Re[2]: Опять про исключения бизнес-процесса (2017 год)
От: Shmj Ниоткуда  
Дата: 31.10.17 23:00
Оценка:
Здравствуйте, sereginseregin, Вы писали:

S>Функция выдаст только название этапа, на котором она споткнулась, так как ограничения в системах (резерв, блокировка счета, технический отказ системы) и сообщения о них для надежности прописываются максимально простым языком. Название этапа не помогает пользователю принять решение. Блокировка счета может быть отменена через секунду после неудачной операции, поэтому пользователю лучше предварительно указать на возможные ошибки с предоставлением максимально подробной информации.


Вопрос вот в чем: будете ли вы использовать механизм Exception или же вернете код ошибки + доп. инфо?
Re[2]: Опять про исключения бизнес-процесса (2017 год)
От: Shmj Ниоткуда  
Дата: 31.10.17 23:09
Оценка:
Здравствуйте, Qulac, Вы писали:

Q>Перевод денег это довольно долгая операция поэтому лучше возвращать результат в виде объекта представляющего перевод. В одних случаях мы бросаем исключение(нет денег на счете, счет заблокирован), в других информацию об ошибке клиент получает проверяя статус объекта представляющего перевод денег.


Т.е. вы за Exception? Ну вот, а выше говорят что никаких двух лагеней нет и все считают одинаково...
Re[2]: Опять про исключения бизнес-процесса (2017 год)
От: Shmj Ниоткуда  
Дата: 31.10.17 23:11
Оценка:
Здравствуйте, antropolog, Вы писали:

S>>Как предпочитает делать большинство?

A>в подавляющем большинстве случаев использование исключений это ошибка дизайна.

А подробнее. Вот, открытие несуществующего файла -- нужно выбросить Exception или же вернуть код возврата?

Почему вы считаете, что перевод средств с пустого счета чем то отличается от открытия несуществующего файла?
Re[2]: Опять про исключения бизнес-процесса (2017 год)
От: Shmj Ниоткуда  
Дата: 31.10.17 23:12
Оценка:
Здравствуйте, scf, Вы писали:

scf>В настоящее время мнение склоняется к "коды ошибок", но активно использются оба подхода.


В чем преимущество кодов ошибок?
Re[3]: Опять про исключения бизнес-процесса (2017 год)
От: Masterspline  
Дата: 01.11.17 01:52
Оценка:
Y> Ожидаемая/неожидаемая — это не всегда бинарное состояние. Что если ожидаемая, но очень редкая?

Как я понимаю, это зависит от способа, которым ты собираешься реагировать на ошибку. Если сразу после возврата из функции — тогда код возврата, если в неопределенном месте сделать откат — тогда исключение. При этом есть переходная "серая" зона, когда для одного и того же метода возможна в одном проекте обработка кода ошибки, а в другом можно спокойно грохнуть приложение. Для каких-то методов должны быть предусмотрены оба варианта (с кодом ошибки и исключением).
Отредактировано 01.11.2017 1:58 Ssd13 . Предыдущая версия .
Re[3]: Опять про исключения бизнес-процесса (2017 год)
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.11.17 04:05
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, Stanislaw K, Вы писали:


SK>>Предпочитает проверять условия предварительно.

S>Что значит предварительно? Вы проверили, денги были. Пока вызвали -- денег уже нет.
Предварительная проверка нужна независимо от спора коды\исключения.
Re[2]: Опять про исключения бизнес-процесса (2017 год)
От: TG  
Дата: 01.11.17 04:51
Оценка:
Здравствуйте, scf, Вы писали:

scf>В настоящее время мнение склоняется к "коды ошибок", но активно использются оба подхода.


Где пруфы, Билли? Нам нужны пруфы!
Re[4]: Опять про исключения бизнес-процесса (2017 год)
От: TG  
Дата: 01.11.17 04:55
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Предварительная проверка нужна независимо от спора коды\исключения.


Где-то на этом форуме уже обсуждали, что попытаться сразу выполнить операцию без предварительных проверок и проще и дешевле. Тем более, что результат такой проверки может стать неактуальным практически мгновенно.
Re[3]: Опять про исключения бизнес-процесса (2017 год)
От: pagid Россия  
Дата: 01.11.17 05:46
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Почему вы считаете, что перевод средств с пустого счета чем то отличается от открытия несуществующего файла?

Для пользователя программы отличается, а уж Exception или вернуть код возврата это дело техники (ЯП) и вкусов разработчика, команды или того, кто в ней принимает решения.
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Re[6]: Опять про исключения бизнес-процесса (2017 год)
От: TG  
Дата: 01.11.17 06:56
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, TG, Вы писали:


TG>>Здравствуйте, gandjustas, Вы писали:


G>>>Предварительная проверка нужна независимо от спора коды\исключения.

TG>>Где-то на этом форуме уже обсуждали, что попытаться сразу выполнить операцию без предварительных проверок и проще и дешевле. Тем более, что результат такой проверки может стать неактуальным практически мгновенно.
G>

Под "предварительными проверками" я имею в виду: достаточно ли денег на счете, не заблокирован ли счет и тому подобное. Т.е. все то, что находится "по ту сторону" функции Transfer() и характеризует состояние внешнего ресурса.
Re[3]: Опять про исключения бизнес-процесса (2017 год)
От: yenik  
Дата: 01.11.17 07:22
Оценка:
S>Давайте ближе к нашему примеру с переводом средств. Вы бы делали NotEnoughMoneyException или код возврата?

S>В guidelines не вижу нигде совета делать коды возврата для данного сценария, наоборот написано "DO NOT return error codes".


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


X DO NOT use exceptions for the normal flow of control, if possible.

Except for system failures and operations with potential race conditions, framework designers should design APIs so users can write code that does not throw exceptions. For example, you can provide a way to check preconditions before calling a member so users can write code that does not throw exceptions.

The member used to check preconditions of another member is often referred to as a tester, and the member that actually does the work is called a doer.

There are cases when the Tester-Doer Pattern can have an unacceptable performance overhead. In such cases, the so-called Try-Parse Pattern should be considered (see Exceptions and Performance for more information).


Видятся варианты.

1)
TransferValidationResult ValidateTransfer(int toAccount, decimal amount);
long Transfer(int toAccount, decimal amount); // бросает исключение при неуспехе

2)
bool TryTransfer(int toAccount, decimal amount, out TransferValidationResult transferValidationResult);
Отредактировано 01.11.2017 7:23 yenik . Предыдущая версия .
Re: Опять про исключения бизнес-процесса (2017 год)
От: kov_serg Россия  
Дата: 01.11.17 07:28
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Классический пример, фукнция перевода денег на счет:


S>
S>long Transfer(int toAccount, decimal amount);
S>


S>Функция возвращает номер перевода, если успешно. А если не успешно -- возникает исключение.

Какие-то полумеры. Она должна ставить в очередь и возвращать номер по которому можно отслеживать
что происходит с обработкой данного перевода.
Re[2]: Опять про исключения бизнес-процесса (2017 год)
От: TG  
Дата: 01.11.17 07:36
Оценка:
Здравствуйте, kov_serg, Вы писали:

S>>Функция возвращает номер перевода, если успешно. А если не успешно -- возникает исключение.

_>Какие-то полумеры. Она должна ставить в очередь и возвращать номер по которому можно отслеживать
_>что происходит с обработкой данного перевода.

В какую очередь?
Re[4]: Опять про исключения бизнес-процесса (2017 год)
От: TG  
Дата: 01.11.17 07:53
Оценка:
Здравствуйте, yenik, Вы писали:

Y>2)

Y>bool TryTransfer(int toAccount, decimal amount, out TransferValidationResult transferValidationResult);

Те же коды возврата, вид сбоку. С теми же недостатками.

Кроме того FDG:

X AVOID using out or ref parameters.

Using out or ref parameters requires experience with pointers, understanding how value types and reference types differ, and handling methods with multiple return values. Also, the difference between out and ref parameters is not widely understood. Framework architects designing for a general audience should not expect users to master working with out or ref parameters.

Re[4]: Опять про исключения бизнес-процесса (2017 год)
От: Shmj Ниоткуда  
Дата: 01.11.17 07:55
Оценка:
Здравствуйте, yenik, Вы писали:

Y>

Y>X DO NOT use exceptions for the normal flow of control, if possible.


Дык... в том то и дело -- в нормальном случае операция проходит и вы отгружаете товар. А если перевести средства не удалось, то это не стандартная ситуация.

Вот, даже наш местный MVP, спец. по guidelines, рекомендует юзать Exception: http://rsdn.org/forum/philosophy/6951261.1
Автор: gandjustas
Дата: 01.11.17


Получается есть таки 2 лагеря?

Y>Видятся варианты.


Y>1)

Y>TransferValidationResult ValidateTransfer(int toAccount, decimal amount);
Y>long Transfer(int toAccount, decimal amount); // бросает исключение при неуспехе

Пред. проверка обычно проходит иначе. Прежде чем пользователь переводит со счета, он видит остаток. Если там 0, то вы просто не отобразите кнопку "перевести средства" в GUI. Если попытается ввести сумму больше, то вы на уровне проверки вводимых данных не дадите этого сделать.

По этому метод Transfer в обычной ситуации отработает, ведь пред. проверки делаютя в любом случае.

Y>2)

Y>bool TryTransfer(int toAccount, decimal amount, out TransferValidationResult transferValidationResult);

Вот, никогда не видел ничего подобного. В обычном случае операция проходит, ведь пред. проверки делаются всегда.
Отредактировано 01.11.2017 7:56 Shmj . Предыдущая версия .
Re[2]: Опять про исключения бизнес-процесса (2017 год)
От: Shmj Ниоткуда  
Дата: 01.11.17 08:02
Оценка:
Здравствуйте, kov_serg, Вы писали:

S>>Функция возвращает номер перевода, если успешно. А если не успешно -- возникает исключение.

_>Какие-то полумеры. Она должна ставить в очередь и возвращать номер по которому можно отслеживать
_>что происходит с обработкой данного перевода.

Нет, не должна. Функция настолько оптимизирована, что вы можете вызвать ее 100 тыс. раз в секунду. Это на 3 порядка больше, чем количество пиковых операций в самые нагруженные дни (максимум было 100 операций в секунду).

Если можно обойтись без очереди -- нужно обходиться без очереди.

Пользователю приятнее сделать запрос и сразу же получить результат. Чем получить сообщение "спасибо, ожидайте очереди".
Re[5]: Опять про исключения бизнес-процесса (2017 год)
От: pagid Россия  
Дата: 01.11.17 08:03
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Дык... в том то и дело -- в нормальном случае операция проходит и вы отгружаете товар. А если перевести средства не удалось, то это не стандартная ситуация.

Отгружает товар обычно не тот у кого не удалась попытка перевести. Частности конечно, но характерная.

S>Вот, даже наш местный MVP, спец. по guidelines, рекомендует юзать Exception: http://rsdn.org/forum/philosophy/6951261.1
Автор: gandjustas
Дата: 01.11.17

Что юзать (Exception, коды возврата) в значительной степени перпендикулярно тому как организовать обработку ошибок с точки зрения пользователя.

S>Получается есть таки 2 лагеря?

Больше. Но совсем не диаметрально противоположных.
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Re[6]: Опять про исключения бизнес-процесса (2017 год)
От: Shmj Ниоткуда  
Дата: 01.11.17 08:10
Оценка:
Здравствуйте, pagid, Вы писали:

P>Здравствуйте, Shmj, Вы писали:


S>>Дык... в том то и дело -- в нормальном случае операция проходит и вы отгружаете товар. А если перевести средства не удалось, то это не стандартная ситуация.

P>Отгружает товар обычно не тот у кого не удалась попытка перевести. Частности конечно, но характерная.

Почему же не тот? Списали с внутреннего счета, оказали услугу.

S>>Вот, даже наш местный MVP, спец. по guidelines, рекомендует юзать Exception: http://rsdn.org/forum/philosophy/6951261.1
Автор: gandjustas
Дата: 01.11.17

P>Что юзать (Exception, коды возврата) в значительной степени перпендикулярно тому как организовать обработку ошибок с точки зрения пользователя.

Мы не про отображение ошибки для пользователя говорим, это другая тема.

Сейчас именно коды возврата vs Exception.

S>>Получается есть таки 2 лагеря?

P>Больше. Но совсем не диаметрально противоположных.

А что кроме варианта код возврата vs Exception есть другие варианты?
Re[7]: Опять про исключения бизнес-процесса (2017 год)
От: pagid Россия  
Дата: 01.11.17 08:22
Оценка:
Здравствуйте, 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 год)
От: yenik  
Дата: 01.11.17 08:30
Оценка:
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 год)
От: yenik  
Дата: 01.11.17 08:40
Оценка:
Y>>

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
Автор: gandjustas
Дата: 01.11.17


В общем случае ТОЛЬКО исключение.


Согласен, исключения мне нравятся. Но бывают и частные случаи.

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 год)
От: Stanislaw K СССР  
Дата: 01.11.17 09:14
Оценка:
Здравствуйте, Masterspline, Вы писали:

SK>>Предпочитает проверять условия предварительно.


M>Система распределенная и сильно многопоточная. Вот ты проверил, что денег достаточно, начал транзакцию, а бабла-то уже и нет, да и счет закрыт/заблокирован.


Это ОЧЕНЬ маловероятно. Не представляю себе пользователя у которого с его банковским счетом ПОСТОЯННО происходят какие то такие движения, да еще незаметно для него.
Все проблемы от жадности и глупости
Re[6]: Опять про исключения бизнес-процесса (2017 год)
От: vmpire Россия  
Дата: 01.11.17 09:32
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Для начала почитай:

G>

    G>
  1. https://www.artlebedev.ru/best/ui/humaneness/
    G>

Ну, Лебедев-то, как обычно, чрезмерно категоричен. В ряде случаев "бюрократическая форма поиска" гораздо удобнее и универсальнее.
Сейчас на куче сайтов такой "человеческий" поиск только мешает.
Re: Опять про исключения бизнес-процесса (2017 год)
От: neFormal Россия  
Дата: 01.11.17 11:36
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Что если денег на счету не достаточно? Выкинуть исключение NotEnoughMoneyException или же обернуть результат в обертку, где будет код возврата (типа успешно -- значит 0, а -100500 -- значит не хватает денег)?

S>Как предпочитает делать большинство?

хз. я за возврат одного из двух вариантов: Получилось и НеПолучилось(поПричине)
...coding for chaos...
Re[7]: Опять про исключения бизнес-процесса (2017 год)
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.11.17 11:42
Оценка:
Здравствуйте, vmpire, Вы писали:

V>Ну, Лебедев-то, как обычно, чрезмерно категоричен. В ряде случаев "бюрократическая форма поиска" гораздо удобнее и универсальнее.

V>Сейчас на куче сайтов такой "человеческий" поиск только мешает.

А пример можно? есть подозрение что там где мешает нужен не поиск, а подбор по параметрам. Это тоже случай когда потеть должна машина, а не человек, но программисты подумали по-другому.
Re[7]: Опять про исключения бизнес-процесса (2017 год)
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.11.17 11:43
Оценка:
Здравствуйте, TG, Вы писали:

TG>Под "предварительными проверками" я имею в виду: достаточно ли денег на счете, не заблокирован ли счет и тому подобное. Т.е. все то, что находится "по ту сторону" функции Transfer() и характеризует состояние внешнего ресурса.


Я тоже про них.
Re[3]: Опять про исключения бизнес-процесса (2017 год)
От: sereginseregin Россия http://daremanager.sourceforge.net/ru/
Дата: 02.11.17 13:00
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Вопрос вот в чем: будете ли вы использовать механизм Exception или же вернете код ошибки + доп. инфо?

использорвать Exception,
а анализ вероятной ошибки + доп. инфо — это отдельный дополнительный механизм, который желательно запускать до вызова процедуры.
Re[2]: Опять про исключения бизнес-процесса (2017 год)
От: Shmj Ниоткуда  
Дата: 18.11.17 11:46
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Грубо говоря, неинтересно, как функция Transfer сигнализирует о проблеме.


И все же, какой вариант вы бы предпочли? Или в одном месте сделаете так, в другом эдак, без всякого порядка?
Re[3]: Опять про исключения бизнес-процесса (2017 год)
От: Sinclair Россия https://github.com/evilguest/
Дата: 20.11.17 03:19
Оценка:
Здравствуйте, Shmj, Вы писали:
S>И все же, какой вариант вы бы предпочли? Или в одном месте сделаете так, в другом эдак, без всякого порядка?
Если я проектирую какой-то API, то я бы предпочёл быть консистентным. То есть либо везде — возвраты, либо везде — исключения.
Коды возврата — лучше, но они очень требовательны к системе типов. Поэтому в традиционных средах, типа джавы или дотнета, я предпочёл бы исключения, т.к. там с алгебраическими типами плоховато.

Конкретно идея "возвращать -1 вместо идентификатора трансфера" — абсолютное зло, за такое надо карать.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.