Как зайти в Даркнет?!
25th January, 01:11
4
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
893
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
912
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
905
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4380
0
Помогите пожалуйста решить задачи
24th November, 23:53
6084
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4350
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4395
0
Метода Крамера С++
23rd October, 11:55
4308
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Обработка исключений: контракт против исключительного подхода
Я знаю два подхода к обработке исключений, давайте посмотрим на них.
Контрактный подход.
Когда метод не делает то, что он говорит, что он будет делать в заголовке метода, он будет вызывать исключение. Таким образом, метод "promises", что он будет выполнять операцию, и если он не работает по какой-то причине, он будет выдавать исключение.
Исключительный подход.
Только бросать исключения, когда что-то действительно странное происходит. Вы не должны использовать исключения, когда вы можете разрешить ситуацию с обычным потоком управления (если операторы). Вы не используете исключения для потока управления, как в контрактном подходе.
Позволяет использовать оба подхода в разных случаях:
У нас есть класс Customer, который имеет метод под названием OrderProduct.
контрактный подход:
class Customer
{
public void OrderProduct(Product product)
{
if((m_credit - product.Price) < 0)
throw new NoCreditException("Not enough credit!");
// do stuff
}
}
исключительный подход:
class Customer
{
public bool OrderProduct(Product product)
{
if((m_credit - product.Price) < 0)
return false;
// do stuff
return true;
}
}
if !(customer.OrderProduct(product))
Console.WriteLine("Not enough credit!");
else
// go on with your life
Здесь я предпочитаю исключительный подход, так как это не является действительно исключительным, что у клиента нет денег, если он не выиграл в лотерею.
Но вот ситуация, в которой я ошибаюсь в стиле контракта.
Исключительный:
class CarController
{
// returns null if car creation failed.
public Car CreateCar(string model)
{
// something went wrong, wrong model
return null;
}
}
Когда я вызываю метод с именем CreateCar, я чертовски хорошо ожидаю экземпляр Car вместо какого-то паршивого указателя null, который может разрушить мой рабочий код через дюжину строк. Поэтому я предпочитаю контракт этому:
class CarController
{
public Car CreateCar(string model)
{
// something went wrong, wrong model
throw new CarModelNotKnownException("Model unkown");
return new Car();
}
}
Какой стиль вы используете? Как вы думаете, каков наилучший общий подход к исключениям?
Я предпочитаю то, что вы называете подходом "contract". В языке, поддерживающем исключения, нет необходимости возвращать значения null или другие специальные значения, указывающие на ошибки. Я считаю, что гораздо легче понять код, когда он не имеет кучу предложений "if (result == NULL)" или "if (result == -1)", смешанных с тем, что может быть очень простой, простой логикой.
Мой обычный подход заключается в использовании контракта для обработки любого вида ошибки из-за вызова "client", то есть из-за внешней ошибки (т. е. ArgumentNullException).
Каждая ошибка в аргументах не обрабатывается. Возникает исключение, и "client" отвечает за его обработку. С другой стороны, для внутренних ошибок Всегда старайтесь их исправить (как будто вы не можете получить соединение с базой данных по какой-то причине) и только если вы не можете справиться с этим, повторите исключение.
Важно иметь в виду, что большинство необработанных исключений на таком уровне не смогут быть обработаны клиентом в любом случае, поэтому они просто, вероятно, перейдут к самому общему обработчику исключений, поэтому, если такое исключение произойдет, вы, вероятно, FUBAR в любом случае.
Если вы действительно заинтересованы в исключениях и хотите подумать о том, как использовать их для построения надежных систем, рассмотрите возможность создания надежных распределенных систем при наличии программных ошибок .
Оба подхода верны. Это означает, что контракт должен быть написан таким образом, чтобы указать для всех случаев, которые не являются действительно исключительными, поведение, которое не требует создания исключения.
Обратите внимание, что некоторые ситуации могут быть или не быть исключительными в зависимости от того, что ожидает вызывающий код. Если вызывающий ожидает, что словарь будет содержать определенный элемент, и отсутствие этого элемента будет указывать на серьезную проблему, то неспособность найти элемент является исключительным условием и должна вызвать исключение. Если, однако, вызывающий объект на самом деле не знает, существует ли элемент, и одинаково готов обрабатывать его присутствие или его отсутствие, то отсутствие элемента будет ожидаемым условием и не должно вызывать исключение. Лучший способ справиться с такими изменениями в ожиданиях вызывающего абонента - это указать в контракте два метода: метод DoSomething и метод TryDoSomething, например
TValue GetValue(TKey Key); bool TryGetValue(TKey Key, ref TValue value);
Обратите внимание, что, хотя стандартный шаблон 'try', как показано выше, некоторые альтернативы также могут быть полезны, если вы разрабатываете интерфейс, который производит элементы:
// In case of failure, set ok false and return default<TValue>. TValue TryGetResult(ref bool ok, TParam param); // In case of failure, indicate particular problem in GetKeyErrorInfo // and return default<TValue>. TValue TryGetResult(ref GetKeyErrorInfo errorInfo, ref TParam param);
Обратите внимание, что использование чего-то вроде обычного шаблона TryGetResult в интерфейсе сделает интерфейс инвариантным по отношению к типу результата; использование одного из шаблонов выше позволит интерфейсу быть ковариантным по отношению к типу результата. Кроме того, это позволит использовать результат в объявлении 'var':
var myThingResult = myThing.TryGetSomeValue(ref ok, whatever);
if (ok) { do_whatever }
Не совсем стандартный подход, но в некоторых случаях преимущества могут оправдать его.