Современный способ обработки ошибок...

Я'долго размышлял над этой проблемой на некоторое время теперь и найти себя в постоянном поиске оговорок и противоречий, поэтому я'м надеясь, что кто-то может подготовить заключение к следующему:

За исключения за коды ошибок

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

Но - для меня это, кажется, противоречит...

Кодировка для интерфейсов, а не реализаций

Мы код для интерфейсов и абстракций, чтобы уменьшить связь. Мы не'т знаю, или хочу знать, конкретного типа и реализации интерфейса. Так как мы можем знать, какие исключения, мы должны поймать? Реализация могла бросить 10 различных исключений, или он может бросить никто. Когда мы ловим исключение, конечно, мы'повторно делать предположения о реализации?

Если - интерфейс...

Технические характеристики исключением

Некоторые языки позволяют разработчикам утверждать, что определенные методы бросить некоторые исключения (на Java, например, использует "бросков" сайта.) Из вызывающего кода'с точки зрения это выглядит нормально - мы точно знаем, что исключения, которые мы, возможно, потребуется, чтобы поймать.

Но - это, видимо, предполагает...

Дырявой абстракцией

Зачем интерфейс указать, какие исключения могут быть брошены? Что если реализация не'т нужна, чтобы бросить исключение, или должен бросить другие исключения? Там's нет пути, на уровне интерфейса, чтобы знать, какие исключения реализация может хотеть бросить.

Так что...

К заключению

Почему предпочтительны исключения, когда они выглядят (в моих глазах) противоречит программного обеспечения наилучшей практики? И, если коды ошибок так плохо (и я не'т должны быть проданы на пороки кодов ошибок), есть еще альтернатива? Что сейчас (или скоро будет) состояние техники для обработки ошибок, которая удовлетворяет требованиям лучшей практики, как описано выше, но не'т полагаться на вызывающий код проверки возвращаемого значения кодов ошибок?

Комментарии к вопросу (4)
Решение

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

Это не всегда так: например, взгляните на объективные-C (в рамках Фонда). Там NSError является предпочтительным способом обработки ошибок, несмотря на то, что Java-разработчик назвала бы правда исключения: @попробуйте, @лови, @кинь, класса NSException и т. д.

Однако это правда, что многие интерфейсы утечки их абстрактности исключений. Я считаю, что это вина не наша "исключение" в стиле погрешности распространения/обработки. В общем я считаю, что лучший совет о обработка ошибок это:

Устранить ошибку/исключение на низком уровне, период

Я думаю, что тот, кто придерживается, что правило, сумма на "утечки" от абстракций может быть очень ограничено и содержится.

О том, были ли исключения, метод должен быть частью его декларации, я считаю, что они должны: они являются частью договор определенные этим интерфейсом: этот метод делает, или не с B или C.

Например, если класс-это синтаксический анализатор XML, часть его должна быть конструкция, чтобы указать, что XML-файла-это просто неправильно. В Java, вы обычно делаете так, объявив исключения вы планируете встречи и добавляя их в "бросков" часть объявления метода. С другой стороны, если один из алгоритмов разбора не удалось, там's нет причин, чтобы передать исключение выше необработанных.

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

Кроме того, я думаю, что создатели Явы были очень сильные причины безопасности исключений объявление метода/определение.

Одна последняя вещь: в некоторых языках, таких, например, имеют другие механизмы обработки ошибок и просто не включают метательные возможности. Там, 'исключения' из рода автоматически поднимается, когда постусловие для обычной не устраивает.

Комментарии (15)

Я хотел бы лишь отметить, что исключения и коды ошибок, разве'т единственный способ справиться с ошибками и альтернативного путей кода.

Из ума, вы можете иметь подход, как принято Хаскелл, где ошибки могут быть сообщены через абстрактные типы данных с несколькими конструкторами (думаю дискриминируемых перечисления или нулевые указатели, но и безопасным с точки зрения типов с возможностью добавления syntatic сахара или вспомогательные функции, чтобы сделать код потока выглядит хорошо).


func x = do
    a 
Комментарии (3)

Да, исключения могут вызвать дырявых абстракций. Но коды ошибок не еще хуже в этом плане?

Один из способов борьбы с этой проблемой является интерфейс точно указать, какие исключения могут быть брошены при каких обстоятельствах и заявить, что реализации должны сопоставить свои внутренние исключения модели данной спецификации, ловя, конвертации и повторной генерации исключения в случае необходимости. Если вы хотите "и префект" и интерфейс, что's пути, чтобы пойти.

На практике, это'ы, как правило, достаточно указать исключения, которые логически являются частью интерфейса и которой клиент может хотят поймать и что-то делать. Это'ы вообще понял, что там могут быть и другие исключения, когда произойдет низкоуровневых ошибок или проявляется ошибка, и что клиент может только обрабатывать как правило, показывая сообщение об ошибке и/или закрытие приложения. По крайней мере, исключение по-прежнему может содержать информацию, которая поможет диагностировать проблему.

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

Комментарии (6)

Много хороших вещей здесь, я'd только хотел добавить, что мы все должны быть осторожны код, который использует исключения как часть нормального потока управления. Иногда люди попадают в такую ловушку, где все это'т обычное дело становится исключением. Я'вэ даже видели исключение, используемое как условие остановки цикла.

Исключения имею в виду и"то, что я могу'т обрабатывать вот случилось, нужно выходить на кого-то другого, чтобы выяснить, что делать." а пользователь вводит неверный ввод это'т исключение (которое должно быть обработано на месте ввода, снова спрашивая, и т. д.).

Еще один вырожденный случай использования исключений я'видел людей, чей первый ответ является "выбросить исключение." Это почти всегда делается без написания поймать (правило: писать сначала поймать, затем оператор throw). В больших приложениях это становится проблематичным, когда непойманное исключение пузырьки пустоты-регионов и взрывает программы.

Я'м не против исключений, но, похоже, они синглтоны несколько лет назад: используемые слишком часто и невпопад. Они'вновь идеально подходит для использования по назначению, но это дела не так широк, как некоторые думают.

Комментарии (0)

дырявой абстракцией

зачем интерфейс указать, какие исключения могут быть брошенным? Что если реализация не'т придется бросить исключение, или должен бросить другие исключения? Там's нет пути, на уровень интерфейс, чтобы знать, какие исключения реализация может хотите , чтобы бросить.

Неа. Спецификации исключений в той же корзине, что возврата и аргумент - они являются частью интерфейса. Если вы можете'т соответствовать этой спецификации, затем Дон'т реализовать интерфейс. Если вы никогда не выбросите, то, что's прекрасно. Там's ничего дырявый об указании исключений в интерфейсе.

Коды ошибок-это плохо. Они'вновь страшно. Вы должны помнить, чтобы вручную проверить и размножить их, каждый раз для каждого вызова. Это нарушает сухой, для начала, и массово взрывает ваш код обработки ошибок. Это повторение является гораздо большей проблемой, чем любой сталкивается с исключениями. Ты никогда не можешь молча игнорировать исключение, но люди могут и не молча игнорировать коды возврата - однозначно плохо.

Комментарии (6)

Ну обработка исключений может иметь свою собственную реализацию интерфейса. В зависимости от типа исключения, выполнять нужные действия.

Решение вашей проблемы дизайна иметь два интерфейса/реализации абстракции. Для функциональности и прочих для обработки исключений. И в зависимости от типа исключения поймали, называть соответствующее исключение, класс, тип.

Внедрение кодов ошибок-это православный способ обработки исключений. Это как использование строку и строку конструктор.

Комментарии (1)

Им-очень-Хо исключения нужно судить о каждом конкретном случае, потому что, нарушая управление потоком они увеличивают фактическую и предполагаемую сложность кода, во многих случаях излишне, так. Отложив обсуждения, касающиеся исключений внутри функции, которая может действительно улучшить свой поток управления, если посмотреть исключений через границы звоните, рассмотрим следующие:

Позволяя абонента, чтобы пробить свой поток управления может не обеспечить никакой реальной пользы, и быть не может осмысленно разобраться с исключением. Для прямой пример, если один реализует наблюдаемой картины (в таких языках, как C#, где у вас есть события, везде и никаких явных "бросков" в определении), нет фактических оснований, чтобы позволить наблюдателю сломать Ваш контроль потока, если она падает, и нет осмысленно, чтобы справится со своими проблемами (конечно, хороший сосед не стоит выбрасывать при наблюдении, но никто не'ы идеально).

Замечание выше может быть продлен до любого слабосвязанных интерфейсов (как вы отметили); думаю, он'ов на самом деле норма о том, что после ползет вверх 3-6 кадров стека, непойманного исключения, вероятно, закончится в раздел кода, который либо:

  • слишком абстрактно, чтобы справиться с за исключением в любом значимым образом, даже если исключение upcasted;
  • выполняет универсальную функцию (не мог'т заботиться меньше о том, почему вы потерпели неудачу, такие как насос, сообщение, или наблюдаемых);
  • это специфический, но с другой ответственности, и он на самом деле должен'т беспокоиться;

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

Я бы сказал, здесь встает вопрос вкуса и удобства: основной акцент изящно восстановления государства в обоих вызывающего абонента и вызываемого абонента после собой "исключение" и, поэтому, если у вас есть большой опыт в продвижении коды ошибок вокруг (ближайшие из C фон), или если вы'работаете в среде, где исключения могут обернуться злом (с++), я не'т считаю, что бросать вещи вокруг так важно для хороших чистый ООП, что вы можете'т полагаться на старые модели, если вы'вновь с ним некомфортно. Особенно если это приводит к нарушению соц.

С теоретической точки зрения, я думаю, что соц-кошерный способ обработки исключений могут быть выведены непосредственно из наблюдения, что в большинстве случаев прямого абонента интересует только то, что вы не, не поэтому. Вызываемый бросает, кто-то очень близкий выше (2-3 рамки) ловит upcasted версии, и фактическое исключение всегда скатились к специализированным обработчиком ошибок (даже если только калька) - это где АОП пригодится, потому что эти обработчики могут быть горизонтальными.

Комментарии (0)

> в пользу исключения за коды ошибок

  • Оба должны сосуществовать.

  • Возвращает код ошибки, когда вы ожидаете определенного поведения.

  • Исключение вернуться, когда вы не ожидаете определенное поведение.

  • Коды ошибки обычно связаны с одним сообщением, Если тип исключения остается, но сообщение может меняться

  • Исключение трассировки стека, когда код ошибки не'т. Я не'т использовать коды ошибок для отладки сломанной системы.

кодирования интерфейсов, а не реализации

Это может быть специфическими для Java, но когда я заявляю о своей интерфейсы не указать, какие исключения могут быть брошены на реализацию этого интерфейса, он просто не'т смысл.

когда мы ловим исключение, конечно, мы'повторно делать предположения о реализация?

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

как быть, если реализация не'т нужна, чтобы бросить исключение, или должен бросить другие исключения?

Я не'т понять, почему это проблема для вас. Да, вы можете иметь одну реализацию, которая никогда не бросает исключений, и вы можете иметь различные реализации, которая постоянно дает сбои и выдает исключение. Если это'ы, то Дон'т указать любые исключения на интерфейс и ваша проблема решена.

Это что-нибудь изменит, если вместо исключения реализации возвращенный объект результат? Этот объект будет содержать результат ваших действий наряду с какие-либо ошибки/сбои, если таковые имеются. Затем вы можете опросить этот объект.

Комментарии (0)

Я считаю, что исключения позволяют писать более структурированный и лаконичный код для представления данных и обработки ошибок: использование кодов ошибок, требует проверки возврата значения после каждого звонка и решить, что делать в случае неожиданного результата.

С другой стороны я согласен, что исключения раскрыть детали реализации, которые должны быть скрыты в коде вызова интерфейса. Поскольку невозможно знать заранее, какой кусок кода можете скинуть какие исключения (если они не объявлены в сигнатуре метода, как в Java), с помощью исключений мы представляем очень сложных неявных зависимостей между различными частями кода, что противоречит принципу минимизации зависимостей.

Подводя итог:

  • Я думаю, что исключения позволяют более чистого кода и более агрессивный подход к тестированию и отладке, потому что непойманные исключения гораздо более заметным и труднее игнорировать, чем коды ошибок (только плохо).
  • С другой стороны, неперехваченное исключение ошибок, не обнаруженных в ходе проверки могут появиться в производственной среде в виде аварии. В определенных обстоятельствах такое поведение не приемлемо и в данном случае я думаю, что с помощью кодов ошибок, это более надежный подход.
Комментарии (4)

дырявая абстракция

зачем интерфейс указать, какие исключения могут быть брошенным? Что если реализация не'т придется бросить исключение, или должен бросить другие исключения? Там's нет пути, на уровень интерфейс, чтобы знать, какие исключения реализация может хотите , чтобы бросить.

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

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

Комментарии (0)

Право предвзятым либо.

Он может'т быть проигнорированы, он должен быть обработан, это's полностью прозрачный. И если вы используете правильный тип ошибки левой рукой он передает всю ту же информацию, как исключение Java.

Оборотная сторона? Код при правильной обработки ошибок выглядит отвратительно (все механизмы).

Комментарии (2)