1

デバイスを監視し、そのデバイスが使用可能なデータを正常に受信したかどうかを報告するモニタークラスがあります。これはいつでも発生する可能性があります。

クライアントは、デリゲートを渡すことによって独自のモニターを作成し、それを開始して、正常に読み取られたデータまたは一種のドメイン固有の例外タイプ(1つの基本例外タイプ)のいずれかを待ちます。

基本例外タイプのサブタイプをスローし、クライアントが各サブタイプに個別に応答できるようにする慣用的な方法は何でしょうか。

public class MyMonitor
{
  private SuccessHandler _successHandler;
  private ErrorHandler _errorHandler;
  public delegate void SuccessHandler(MyDTO result);
  public delegate void ErrorHandler(MyBaseException exception);

  public MyMonitor(SuccessHandler successHandler, ErrorHandler errorHandler) {
    _successHandler = successHandler;
    _errorHandler = errorHandler;
  }

  public void start() {
    try {
      _successHandler(new MyDTP().doSomethingRisky());
    } catch(Exception e) {
      _errorHandler(e);
    }
  }
}

public class Client {
  static void Main(string[] args) {
    MyMonitor monitor = new MyMonitor(new MyMonitor.SuccessHandler(handleSuccess), new MyMonitor.ErrorHandler(handleException));
    monitor.start();
  }

  static void handleSuccess(MyDTO result) {
    // do something with result
  }

  static void handleException(MyBaseException e) {
    try {
      throw e;
    } catch(UserException mbe) {
      // present message to user
    } catch(DataNotFoundException se) {
      // log error and show generic error message
    } catch(UnexpectedException ue) {
      // log error and try to hide it from the user
    }
  }
}
4

1 に答える 1

2

では、モニター クラスではなくメインで例外を処理してみませんか?

それができない場合は、(少なくとも) 2 つの選択肢があります。

static void handleException(MyBaseException e)
{
  if (e is UserException)
  {
    // present message to user
  }
  else if (e is DataNotFoundException)
  {
    // log error and show generic error message
  }
  elseif (e is UnexpectedException)
  {
    // log error and try to hide it from the user
  }
  else
  {
    // might want to rethrow the exception, do a general handling,...
  }
}

そうすれば、例外を再スローする必要はなく、再度キャッチするだけです。しかし、処理するサブタイプが多数ある場合、これは見苦しくなる可能性があり、ここでマルチディスパッチの出番です。

static void HandleException(MyBaseException e)
{
  HandleSubException((dynamic)e);
}

static void HandleSubException(MyBaseException e)
{
    // might want to rethrow the exception, do a general handling,...
}

static void HandleSubException(DataNotFoundExceptione)
{
    // log error and show generic error message
}

static void HandleSubException(UnexpectedException e)
{
    // log error and try to hide it from the user
}

static void HandleSubException(UserExceptione)
{
    // present message to user
}

これで、独自のメソッドで各例外を処理できるようになり、読みやすく維持しやすくなりました。そうは言っても、これがベストプラクティスに該当するかどうかは完全にはわかりません。

于 2012-05-26T07:32:20.647 に答える