2010-06-14 3 views
3

Какое лучшее место для обработки исключений? BLL, DAL или PL?Где я должен обрабатывать исключения, в BLL, DAL или PL?

Должен ли я разрешать методам в DAL и BLL бросать исключения вверх по цепочке и позволять PL обрабатывать их? или я должен обращаться с ними в BLL?

например

Если у меня есть метод в моей DAL, который выдает «ExecuteNonQuery» и обновляет некоторые записи, а также из-за одного или нескольких причин, 0 строк затронуты. Теперь, как я должен сообщить своей PL о том, произошло ли исключение или на самом деле не было строк, сопоставленных с условием. Должен ли я использовать «try catch» в моем коде PL и сообщить об этом через исключение, или мне нужно обработать исключение в DAL и вернуть некоторый специальный код, например (-1), чтобы позволить PL различать (исключение) и (нет строка соответствует условию, т.е. затронуты нулевые строки)?

+0

0 затронутых строк не вызывают исключения. Действительно ли ваш вопрос «Должен ли я делать исключение, если на него влияют 0 строк?» Думаю, для этого вы получите разные ответы. – mbeckish

+1

@mbeckish: Да, но люди, которые говорят, что вы должны (всегда) делать это неправильно! (если ваша программа не может функционировать должным образом после запроса, который имеет «0 строк», и это связано с непредвиденным условием (недействительным вводом), тогда вы должны выкинуть исключение приложения (или подобное) с информацией, касающейся перманентной информации, но это край дело). – FastAl

+0

@FastAl - Я не выступал за этот курс действий - просто пытаюсь прояснить вопрос. – mbeckish

ответ

4

Нет смысла допускать исключение, которое выбрасывается в пузырь DAL до PL - как пользователь должен реагировать, если соединение с базой данных не может быть установлено?

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

+0

Будьте готовы к тому, чтобы меня нивелировали ... эта стратегия сегодня не популярна :) – joshlrogers

+0

+1, ваш ответ был в порядке и даже более подробный, чем мой. –

+0

Я не собираюсь ниспровергать вас ... НО ... - некоторые ошибки в порядке для обработки на более низких уровнях. Это будет не жесткое правило, а ум. Но нет подключения к БД? PL должен знать, даже если вы измените сообщение. - не проглатывая их - АМЕН! НИКОГДА не должен кто-нибудь это делать. Лучшие практики также требуют, чтобы всегда регистрировалось ex.tostring, а не только сообщение. И наличие PDB w/line #s (даже если это сложно, и вам нужно бороться с политикой безопасности/политикой). Поэтому полный стек в журнале. Разные машины? По-прежнему нужно сохранять невнимательность, это возможно. – FastAl

1

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

-2

Вопрос к тому, является ли данное исключение релевантным? Если это исключение доступа к данным, оно должно быть уловлено в DAL. Если это логическое исключение, он должен быть пойман в BLL. Если это исключение для презентации, то в PL.

Например, если ваш DAL выдает исключение, он должен возвращать нулевой или ложный или любой другой случай, который может быть в вашем BLL. Ваш BLL должен знать, что делать, если DAL возвращает нуль, возможно, он передает его прямо, возможно, он пытается вызвать другую функцию и т. Д. То же самое происходит с вашей PL, если BLL проходит через нуль из DAL или возвращает что-то конкретное то уровень представления должен быть в состоянии уведомить конечного пользователя о возникшей проблеме.

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

По существу вам необходимо подумать с точки зрения separation of concerns, если проблема связана с проблемой данных или логической проблемой, ее следует обрабатывать соответствующим образом.

2

Короткий ответ - это все зависит!

Вы должны только обрабатывать исключение, если можете сделать что-то полезное с ним. «Что-то полезное» снова зависит от того, что вы делаете. Возможно, вы захотите зарегистрировать сведения об исключении, хотя на самом деле это не обрабатывается, и вы должны действительно перебросить исключение после регистрации в большинстве случаев. Вы можете обернуть исключение в другое (возможно, настраиваемое) исключение, чтобы добавить дополнительную информацию в исключение. По мере того как @mbeckish затрагивает, вы можете попытаться восстановить из исключения, повторив операцию, например, вы должны быть осторожны, чтобы не повторять попытку навсегда. Наконец (извините за каламбур) вы можете использовать блок finally для очистки любых ресурсов, таких как открытое соединение с БД. То, что вы решите сделать с исключением, будет влиять на то, где вы его обрабатываете. Вполне вероятно, что не так много полезных вещей, которые можно сделать со многими исключениями, кроме как сообщить пользователю, что произошла ошибка, и в этом случае было бы более чем приемлемо обрабатывать исключение в слое пользовательского интерфейса и сообщать о проблеме пользователю (возможно, вам следует также регистрировать исключение, далее вниз по своим слоям).

Если вы выбрали исключения самостоятельно, вы должны только бросать исключения в «исключительных» условиях, так как есть большие накладные расходы при бросании исключений. В вашем примере вы предлагаете вам подумать о том, чтобы исключить исключение, если никакие записи не обновляются в вашей операции. Это действительно исключительное? Лучше всего в этой ситуации было бы вернуть число обновленных записей - это может все еще быть условием ошибки, которое должно быть сообщено пользователю, но не является исключительным, как ошибка команды, поскольку соединение с БД понизились.

This - разумная статья об оптимальных методах обработки исключений.

+0

> ... и вы должны действительно перебросить исключение после регистрации в большинстве случаев. Я должен с вами не согласиться. Обработка исключений - чрезвычайно дорогостоящий процесс, и если вы делаете что-то правильно, должно быть очень мало случаев, когда у вас даже есть исключение. Когда вы начинаете позволять исключениям контролировать поток вашего приложения, вы открываете для себя массу проблем.Я бы сказал, что вы НИКОГДА не перебрасываете исключение, если у вас нет аргумента ОЧЕНЬ ХОРОШО для этого, и даже тогда аргумент, вероятно, недостаточно хорош. – joshlrogers

+0

Извините @joshrogers, я должен с вами не согласиться. Ловить исключение, записывать его, а затем делать ничего просто неправильно! Наверное, вы имеете в виду, что вам следует вернуть код ошибки, как вы предлагаете в своем ответе. Лично мне не нравится этот шаблон. Хотя я согласен с тем, что вы не должны использовать исключения для управления потоком, удар, который вы можете получить повторно бросать исключение в этом случае, кажется, не имеет большого значения, поскольку, в конечном счете, что-то пошло не так с приложением. Это также IMHO приводит к более чистым кодам, так как вам не нужно проверять коды возврата везде. – s1mm0t

+0

Что делать, если я регистрирую свои исключения в каком-то источнике журнала. , например. Если в одном из методов DAL я регистрирую свое исключение, и если этот метод вызывается из нескольких мест в PL, как журнал будет передавать информацию, откуда произошла ошибка в коде PL? – teenup

3

Это огромная тема с множеством ненужных споров (люди с громкими голосами, дающие плохую информацию!) Если вы готовы справиться с этим, следуйте советам s1mm0t, это в основном приятно.

Однако, если вы хотите ответить одним словом, поместите их в PL. Серьезные. Если вы можете с ним справиться, поместите свою обработку ошибок в глобальный обработчик исключений (все ошибки должны регистрироваться и давать код для поиска журнала в целях производства по соображениям безопасности (esp if web), но дать полную информацию во время разработки для скорости).

Редактировать: Вы должны иметь дело с некоторыми ошибками во всем мире, но это не норма «каждая функция». Большую часть времени они могут пузыриться до PL и обрабатывать глобальную ошибку .NET с помощью вашего собственного кода: зарегистрировать полный стек вызовов оттуда через общую процедуру, доступную из всех трех уровней с помощью обработчиков событий (см. EDIT внизу сообщения). Это означает, что вы не попробуете/поймаете посыпать весь ваш код; просто разделы, которые вы ожидаете, и ошибки, и можете обрабатывать их прямо там, или некритические разделы, с помощью которых вы регистрируете ошибку и информируете пользователя о недоступных функциях (это еще реже и для сверхнадежных/критических программ)

Кроме того, при работе с ограниченными ресурсами я часто использую ключевое слово «using» или try/finally/end try без catch. для флагов предотвращения многопоточности/мьютекса/повторного входа/и т. д. вам также нужно попробовать/наконец во ВСЕХ случаях, чтобы ваша программа все еще работала (особенно с учетом состояния приложений).

Если вы неправильно используете исключения (например, чтобы иметь дело с не-ошибками, когда вы должны использовать оператор IF или проверять его, операция iffy будет работать до того, как вы его попробуете), эта философия будет распадаться больше.

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

EDIT: другой необходимости, по крайней мере, имея протоколирования подпрограмму в PL - это будет работать по-разному в зависимости от платформы. Приложение, над которым мы работаем, использует BLL/DAL с 3 версиями PL: версию ASP.Net, версию winforms и версию тестирования регрессионного режима консольного приложения. Процедура ведения журнала, которая называется, фактически находится в BLL (DAL только порождает ошибки или полностью обрабатывает все, что получает или перебрасывает их). Однако это вызывает событие, которое обрабатывается PL; в Интернете он помещает его в журнал сервера и выводит сообщение об ошибке веб-стиля (дружественное сообщение для производства); в WinForms появляется специальное окно с информацией о технической поддержке и т. д. и регистрирует ошибку за кулисами (разработчики могут сделать что-то «секретное», чтобы увидеть полную информацию). И, конечно, в тестовой версии это гораздо более простой процесс, но другой.
Не знаете, как бы я сделал это в BLL, за исключением передачи параметра «какая платформа», но поскольку он не включает winforms или asp-библиотеки, на которые зависит ведение журнала, это все равно будет хитростью.

+0

В одном из моих проектов я обрабатывал все исключения в PL и записывал их только в PL. Но это делает код PL очень загроможденным, а реальная логика нечитаема. Это также одна из причин, я хочу регистрировать исключения на нижних уровнях. – teenup

+0

Если вы используете winforms или asp.net, вам не нужно загромождать PL с помощью обработчиков. Используйте глобальные дескрипторы исключений, предоставляемые этими фреймворками. Вы устанавливаете его в глобальном asp или sub main, затем, boom, каждое действие hit/UI получает свой собственный «try catch» перед вводом вашего кода, и все ошибки переходят в одно место в вашем коде. Это здорово! Да, есть недостатки и ограничения, но они не являются непреодолимыми. – FastAl

0

Все слои в вашем приложении должны обрабатывать исключения изящно. Это известно как перекрестный кукуруза, потому что он появляется во всех ваших слоях. Я верю, что с использованием рамки, такой как Enterprise Exception Block с единицей, вы получите лучший код в целом. Взгляните на этот пост

http://msdn.microsoft.com/en-us/library/ff664698(v=PandP.50).aspx

Это займет некоторое время, чтобы справиться с этим, но есть много примеров и скринкаст вокруг там.

0

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

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

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^