2012-05-26 2 views
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 
    } 
    } 
} 

답변

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,... 
    } 
} 

그냥 다시 잡기 위해, 예외를 다시 발생하지 않아도 그런 식으로. 하지만 여기 당신이 처리 할 수있는 많은 하위 유형이있는 경우 추한 수는 multidispatch이 들어오는 곳

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 
} 

지금 당신은 자신의 방법으로 각각의 예외 경향이 있습니다.이며 읽기 및 유지 관리가 훨씬 쉽습니다. 그런데, 이것이 최선의 관행에 해당되는지 확실하지 않습니다.

+0

제안 해 주셔서 감사합니다. 나는 일반적인 예외 위임 처리기가 Main에서 예외를 처리하는 것과 다르지 않다는 것에 동의한다. 더 구체적인 대표자를 사용하여 이벤트로 제공 할 것입니다. 그런 식으로 아무도 자신의 메인에서 예외를 처리 할 수 ​​없지만 리스너를 등록 할 수 있습니다. – rretzbach

+1

@rretzbach 선택 사항으로 만들려면 이벤트를 사용해야합니다 (대리인을 전달할 필요없이 그냥 구독 할 수 있음). 예외는 여러분의 코드에서 다루어야 할 예외적 인 오류라고 생각합니다. 지금은 마치 프로그램의 흐름을 제어하는 ​​데 사용하려는 것처럼 내게 거의 들립니다. 예외가있는 경우 예외를 throw하고 main()에서 처리합니다. 알림 만 사용하는 이벤트 인 경우 – Brunner

관련 문제