Как библиотека классов должна представлять уведомление пользователю / пользовательскому интерфейсу? - PullRequest
4 голосов
/ 11 июня 2011

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

A) Бросьте исключение, пусть пользовательский интерфейс поймает его и справится с ним.

B) Создает какое-либо событие, которое пользователь может прослушивать.

C) Сделай что-нибудь еще

Что из перечисленного ты делаешь?Если и то, и другое, каковы ваши рекомендации относительно того, когда выдавать исключение или инициировать событие?Каковы плюсы и минусы каждого?

Редактировать:

Вот пример, с которым я сталкиваюсь.Моя библиотека использует стороннее приложение для печати этикеток доставки, запуская стороннее приложение и передавая XML-файл в качестве аргумента, который обрабатывается как операция пакетного типа.Если стороннее приложение уже открыто пользователем, оно должно быть закрыто, прежде чем моя библиотека сможет вызвать его для пакетной операции.Моя библиотека проверяет, запущено ли приложение, и если оно есть, оно просто останавливается и должно уведомить пользователя, что ему следует закрыть стороннее приложение и повторить попытку.Я полностью ожидаю, что это произойдет как часть нормального использования библиотеки.Бросить исключение или вызвать событие?

Ответы [ 6 ]

4 голосов
/ 11 июня 2011

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

В общем случае «уведомление» должно предлагать событие..

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

2 голосов
/ 11 июня 2011

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

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

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

См. Также этот поток .


Что касается вашей ситуации:

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

Однако верно также и то, что эта ситуация не является единственной - исключительной , поскольку на некотором уровне она известна и ожидается.

Поэтому я предлагаю вам сделать следующее:

  • ввести свойство CanRunNow, которое определяет, запущено ли приложение;
  • проверить это свойство в коде клиента перед вызовом Runметод (предположим, он так называется);
  • в методе Run, выполните проверку еще раз, и если на этот раз CanRunNow равно false, сгенерируйте исключение (теперь этоЭто неожиданно!)

Таким образом, вы предоставляете клиентскому коду свободу и ответственность за то, чтобы либо выполнить проверку и оставаться в безопасности, либо идти вперед (и, возможно, получить исключение). Какое бы поведение вы ни выбрали, обязательно запишите это!

1 голос
/ 11 июня 2011

Если ожидается, значит, это событие. Если этого не ожидается, это исключение.

Только не позволяйте "C" быть "показывать окно сообщения".

0 голосов
/ 11 июня 2011

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

Что-то вроде:

interface IErrorAndStatusReporter {
   void ReportStatus(string message);
   void ReportError(Exception err, string message);
   ...
}

Система верхнего уровня передает экземпляр этого в классы / методы, которые в этом нуждаются.

Преимущество заключается в том, что я могу отделить отчетность от реализации логики. Код легче тестировать и использовать повторно. Отчетность реализуется по-разному в зависимости от среды:

  • Приложение с графическим интерфейсом: открыть диалог или показать в каком-то списке ошибок
  • Консольное приложение: запись в консоль
  • Служба Windows: войдите в журнал событий и отправьте электронное письмо
0 голосов
/ 11 июня 2011

Есть 2 вещи, которые вы хотите уведомить: пользовательские события и обработка ошибок.

Я согласен с другими ответами, перехватываю исключение и делегирую его, как событие, в GUI

0 голосов
/ 11 июня 2011

Вы говорите, что событие - это ожидаемое (то есть не исключение), поэтому, я думаю, вы ответили на свой собственный вопрос ... Определенно, B, по моему мнению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...