2

여러 프로젝트에서이 문제가 몇 번이나 발생했습니다. 일반적으로 사용하는 것보다 더 나은 솔루션이 있는지 궁금해했습니다.오류 처리를위한 디자인 패턴

우리는 실행해야 할 일련의 메소드를 가지고 있으며, 메소드 중 하나에서 문제가 발생했는지 알기를 원한다면 (이전의 변경 사항을 취소 할 수 있습니다 ...), 일반적으로 난 그냥 궁금

private bool SomeMethod() 
{ 
    bool success = true; 
    string errorMessage = null; 
    success = TestPartA(ref errorMessage); 
    if (success) 
    { 
     success = TestPartB(ref errorMessage); 
    } 
    if (success) 
    { 
     success = TestPartC(ref errorMessage); 
    } 
    if (success) 
    { 
     success = TestPartD(ref errorMessage); 
    } 
     //... some further tests: display the error message somehow, then: 
     return success; 
} 

private bool TestPartA(ref string errorMessage) 
{ 
    // Do some testing... 
    if (somethingBadHappens) 
    { 
     errorMessage = "The error that happens"; 
     return false; 
    } 
    return true; 
} 

(이 내 질문) 이런 종류의 극복을위한 더 나은 방법이 있다면 다음 (의사 C#을 내가 가장 익숙한 해요 무엇 때문에). 나는 그것이 더 매끄러 워야하는 것처럼 보이는 무언가를 위해 많은 if 진술을 쓰는 것을 끝내는 것처럼 보인다.

나는 델리게이트 함수 집합에 대한 반복을 제안했지만, 그것을 할 수있는 확실한 방법이 없다면 솔루션을 과도하게 설계 할 것이라고 걱정할 것입니다.

+1

정말 오류 인 경우 예외가 발생해야합니다. – Polyfun

답변

6

아마 예외를 사용해야한다고 생각합니다. 일반적으로 응용 프로그램의 "최상위 수준"에서만 예외를 catch해야합니다.

private void TopLevelMethod() 
{ 
    try 
    { 
     SomeMethod(); 
    } 
    catch (Exception ex) 
    { 
     // Log/report exception/display to user etc. 
    } 
} 

private void SomeMethod() 
{ 
    TestPartA(); 
    TestPartB(); 
    TestPartC(); 
    TestPartD(); 
} 

private void TestPartA() 
{ 
    // Do some testing... 
    try 
    { 
     if (somethingBadHappens) 
     { 
      throw new Exception("The error that happens"); 
     } 
    } 
    catch (Exception) 
    { 
     // Cleanup here. If no cleanup is possible, 
     // do not catch the exception here, i.e., 
     // try...catch would not be necessary in this method. 

     // Re-throw the original exception. 
     throw; 
    } 
} 

private void TestPartB() 
{ 
    // No need for try...catch because we can't do any cleanup for this method. 
    if (somethingBadHappens) 
    { 
     throw new Exception("The error that happens"); 
    } 
} 

예제에서는 내장 된 System.Exception 클래스를 사용했습니다. 자신 만의 파생 예외 클래스를 만들거나 System.Exception에서 파생 된 내장 클래스를 사용할 수 있습니다.

+0

당신이 옳다고 생각합니다. ShellShock에게 감사드립니다. 내 자신의 예외를 던지기를 생각하지 않았거나 거의 모든 시나리오를 다루는 예외를 다시 던지지 않았다. – loxdog

2

나는 'Fail Fast'로 알려진 원칙을 고수하려고합니다. 메서드는 오류가 발생했을 때 실패하고 오류의 세부 정보로 즉시 반환됩니다. 호출 방법은 다음 (, 그것은 UI 바인딩 방법의 경우 오류를 표시, 세부 사항을 기록, 호출자에 등 예외를 재 - 던져) 적절하게 응답합니다 -

http://en.wikipedia.org/wiki/Fail-fast 그러나

,이 의미하지 않는다 예외를 사용하여 응용 프로그램의 흐름을 제어합니다. 내가 (예를 들어)로 코드를 다시 써서

귀하의 경우에는

http://msdn.microsoft.com/en-us/library/dd264997.aspx

: - : - 당신은 그것으로 거래는 일반적으로 나쁜 연습을 할 수있다 때 그냥 예외를 발생시키는

private bool SomeMethod() 
{ 
    bool success = false; 

    try 
    { 
     TestPartA(); 
     TestPartB(); 
     TestPartC(); 
     TestPartD(); 

     success = true; 
    } 
    catch (Exception ex) 
    { 
     LogError(ex.Message); 
    } 

    //... some further tests: display the error message somehow, then: 
    return success; 
} 

private void TestPartA() 
{ 
    // Do some testing... 
    if (somethingBadHappens) 
    { 
     throw new ApplicationException("The error that happens"); 
    } 
} 
+0

ShellShock과 거의 같은 대답입니다. 조금 느립니다! 나는 패스트 패스트 원칙을 좋아한다. 귀중한 독서. – loxdog

+1

msdn : _ "ApplicationException 클래스 대신 Exception 클래스에서 사용자 지정 예외를 파생시켜야합니다. 코드에 ApplicationException 예외를 던져서는 안되며 원래 예외를 다시 throw하지 않는 한 ApplicationException 예외를 catch하면 안됩니다 . "_ – Gusdor

4

당신은 아마도 "Open/Closed" section of the SOLID Principle.을 살펴볼 수 있습니다. ITestRule 인터페이스를 만들 수 있습니다.이 인터페이스에는 CheckRule()이라는 메서드가 포함되어있어 메시지를 업데이트하고 bool을 반환 할 수 있습니다. 그런 다음 테스트 할 각 규칙에 대한 인터페이스 구현을 만들고이 클래스를 List<ITestRule> 객체에 추가합니다. 위의 Redmondo 예에서, 나는 다음과 같이 바꿀 수 :

var discountRules = 
       new List<ITestRule> 
        { 
         new TestPartA(), 
         new TestPartB(), 
         new TestPartC(), 
         new TestPartD(), 
        }; 

당신은 다음 것입니다 각 클래스를 통해 루프가 CheckRule() 메소드를 실행 평가자에 새로운 List<ITestRule>을 통과 할 것입니다.

+0

이것은 작동 할 것이고 (앞으로는 이와 같은 것이 필요할 수도 있습니다.)하지만 나는 내가 필요로하는 것에 대한 과도한 엔지니어링에 대해 유죄라고 생각합니다. – loxdog