2011-10-01 8 views
1

나는 예외 구동 프로그래밍을해서는 안되는 것을 알고있다. 프로그래머가 어떤 점에서 MyDeviceInstance.Connect를 호출하고 현재 내 문제가 나타나는 곳에서 장치와의 연결을 설정해야하는 라이브러리를 구축하고 있습니다. "연결/연결 끊기"방법에 대한 예외 구동 프로그래밍을 피하는 방법

나는 무효 연결() 나의 연결 방법을 썼다, 그래서 (실제로 난 아무것도 필요가 없기 때문에) 나는 아무것도 반환하지 해요,하지만 난 많은 상황에서 예외가 발생합니다 :

  1. 연결이 이미
  2. 을 존재하는 경우 MyDeviceInstance에서 일부 잘못된 설정이있는 경우
  3. deviceConnect이 실패 내 상호 운용성 방법 (그 뜻이 많은 오류을 나타내는 int를 반환하기 때문에 여기가 가장 큰 문제가되어 있으면)

은 void 대신 boolean을 반환합니까? 예외가 발생할 가능성이 많습니다.

이 질문의 두 번째 부분은 void Update()이라는 또 다른 방법입니다. 이 메서드는 MyDeviceInstance가 이미 연결된 경우에만 작동합니다.

  • 다른 상호 운용성 오류를

    1. 연결이
    2. 연결이 어떤 이유로 손실이없는 (그리고 프로그래머가이 일 것으로 기대하지 않지만 수) :이 경우에 나는 예외를 던질거야

    업데이트는 모든 예외를 throw하지 않고 (적어도 "연결이 없습니다"와 같은 일반적인 오류를 제한하기 위해) bool 값을 반환해야합니까? 내가 한 지점에 더 정확하게해야

    : 어떤 대답

    EDIT 1

    덕분에 우리는 내가 내 메서드를 호출합니다 USB 장치에 대해 이야기하고 있기 때문에 업데이트을 업데이트하면 장치에 따라이 방법이 실패 할 수 있습니다 (연결되어있는 경우). 더 중요한 것은 장치를 다시 연결하면 interop 메서드가 다시 연결될 필요가 없으며 (예 : 내부적으로 어떻게 작동하는지 모르겠 음) 다시 작업을 시작합니다 (정상적인 메서드는 동일하게 수행함).

    업데이트 방법은 장치를 분리해야합니까? 프로그래밍 방식으로 말하는 것은 예외이지만 사용자가 말하는 것은 아주 정상적인 상황입니다.

  • +2

    두 번째 질문에 대답하려면 네, 단절된 미디어 장치가 확실히 예외적 인 상황입니다. 귀하의 원래 질문은 비즈니스 규칙을 예외로 포함해야하는지 여부이며, 답변은 IMHO가 아닙니다. – Furbeenator

    +0

    두 번째 질문에 대한 답을 보내 주셔서 감사합니다. 그러나 나는 내 응용 프로그램에서 비즈니스 로직을 던지는 것에 대해 이야기 한 적이 없다고 생각합니다. 내가이 일을하는 곳을 나에게 지적 해 줄 수 있니? (가능하다면) –

    +0

    나는 당신이 당신이 찾고있는 오류를 설명했을 때 나는 오해했다고 생각한다. 사용자가 데이터를 처리하는 대신 예외를 사용하여 데이터의 유효성을 검사하는 방식으로 읽습니다. 오류 트래핑의 범위가 단순히 연결/연결 끊기 작업을 확인하는 것보다 광범위하다고 생각했습니다. – Furbeenator

    답변

    1

    , 메소드가 예외가 아닌 다른 수단을 통해 특별한 결과를 표시해야합니다. 호출 코드가 비정상적인 결과를 처리 할 준비가되지 않으면 그러한 결과는 예외를 야기합니다. 불행히도, 호출자가 어떻게 든 말하지 않는 한 호출자가 비정상적인 결과를 기대하는지 여부를 마술로 알 수있는 방법은 없습니다. 클래스가 "해봐요"와 "TryDoSomething"방법의 쌍을 제공하는 .NET에서 일반적인 패턴은 다음과 같습니다 솔직히

     
    ResultType DoSomething(); 
    Boolean TryDoSomething(ref ResultType result); 
    

    을, 나는 후자의 배합이 잘 표현 될 것이라고 생각 같은 :

     
    ResultType TryDoSomething(ref Boolean ok); 
    

    혹은 :

     
    ResultType TryDoSomething(ref Exception ex); 
    

    여기서 "예", null이 아닌 경우를 제외하고 있기 때문에 실제로 h는하지 않습니다, 예외 (예)가 있지만 빈 스택 트레이스 (해봐요에 의해 발생 된 것을 나타냅니다 ave 던져졌다). 경우에 따라 다른 패턴이 될 수있다 :

    예기치 않은 상황이 발생하면
     
    ResultType TryDoSomething(Action failureAction); 
    

    이 코드는 매개 변수는 상황이 발생한 상황의 세부 사항을 제공하여, 지정된 대리자를 호출합니다. 이 대리자는 TryDoSomething이 수행하던 작업을 포기하기 전에 호출 할 수 있기 때문에 가능한 경우보다 더 나은 오류 처리 및 복구를 허용 할 수 있습니다. 예를 들어 대리자를 제공하는 객체가 취소 요청을받을 때까지 또는 TryDoSomething()이 작업을 다시 시도하도록 지시 할 수 있습니다.

    +0

    당신은 대답을 정말 잘 설명해 주셔서 감사합니다. –

    2

    예외적 인 경우 예외를 사용하십시오. 그렇다면 예외적 인 상황을 어떻게 알 수 있습니까? 그것은 맥락에 달려 있으며, 그것에 대한 엄격하고 빠른 규칙이 없습니다. 예외는 무거운 가중치이므로 응용 프로그램에서 정상적인 흐름을 위해 예외를 사용해서는 안됩니다.

    언급 한 사례에서 대부분은 예외를 보증하는 것으로 보입니다.

    Connect의 경우 이미 존재하는 연결은 예외적 인 경우는 아닙니다. 원한다면 멱등 원으로 만들 수 있습니다. Interop deviceConnect 실패는 확실히 예외적 인 상황입니다. 네가 예상하지 못한 것. 예외 코드를 여기에 올리면 종료 코드를 의미있는 예외로 매핑 할 수 있습니다.

    Update의 경우 연결이 존재하지 않는 것은 예외적 인 경우 일 수 있으며 예외를 발생시킬 수 있습니다. 또한 손실 된 연결은 예외적입니다. 이렇게하면 자신의 상황을 평가할 수 있습니다.

    또한 boolean이 아닌 실제로 오류 인 int를 반환 할 수 있습니다.

    0

    연결/업데이트 방법이 실패 할 수 있으면 실패/성공에 대한 부울을 꼭 반환하십시오. 프로그래머가 필요한 경우 액세스 할 수있는 클래스에 오류 코드 및/또는 오류 메시지 메서드/속성을 추가 할 수도 있습니다.

    2

    예외는이 상황에서 사용하는 것이 옳습니다.

    1. 예외적으로 예외가 발생했음을 나타냅니다. 일반적으로 연결 성공을 예상하므로 연결 실패는 예외적 인 이벤트를 나타냅니다. 호출이 실패한 이유를

    2. 예외가 에 대한 풍부한 정보를 제공 할 수 있습니다.

    3. 예외는 무시할 수 없습니다 (잘 숙지해야합니다). 요청 된 조치가 유효하지 않은 요청을 나타낼 때, 호출 메소드가이를 무시하고 연결을 계속 악용하는 것은 쉽습니다. 예외는 호출자가 문제를 처리하도록합니다.

    예외 사용에 대한 주요 논쟁은 일반적으로 성능을 중점으로합니다. 모든 오류 전달에 예외를 사용하는 경우 문제가 될 수 있습니다. 그러나 수행중인 조치가 일반적으로 성공해야하는 경우 예외는 성능에 영향을주지 않습니다.

    +0

    사실이지만 모든 종류의 예외 상태를 던지고 있습니다. 그 예상 된 "예외"를 포착하는 것이 더 나은 선택이라고 생각합니다. 그러나 날짜가 아닌 0으로 나누는 것과 같은 예외가 프로젝트의 제약에 대해 허용 가능한 범위를 벗어나는 경우 예외가 발생하지 않아 예외로 처리해야합니다. 예상치 못한 경우를 제외하고 예상되는 트랩 오류. – Furbeenator

    +1

    "예상되는"예외 "를 포착하는 것이 더 나은 선택이라고 생각합니다." - 왜?그것들은 여전히 ​​모두 예외적 인 사건이며, 예외를 던지면 실패에 대한 상세한 세부 정보를 얻을 수 있습니다. 그것은 오류 코드 +와 같습니다. 리턴 코드로 멍청하고 그 실패에 대한 모든 상세한 정보를 잃을 이유가 없습니다. 또한 기존 .NET Framework 구현을 고려하면 연결 문제가있을 때 예외가 발생합니다. –

    +0

    예외를 둘러싼 또 다른 주장은 디버깅입니다. 예외 상황을 깨기 위해 분노를 불러 일으키고 누군가가 흐름 제어를 위해 그것을 사용하기 때문에 디버깅하려는 코드에 도달하기 전에 끊어집니다. 더 이상 좋거나 나쁘다고 말할 수 없습니다. – bryanmac

    2

    예외는 예외적이어야하며 흐름 제어에 사용하면 안됩니다.

    앱에 따라 연결이 이미 존재하는 경우 패시브로 되돌릴 수 있습니다.

    잘못된 설정이있는 경우 이는 예외이며 예외가 발생합니다.

    interop 및 연결에 관해서는 bool을 반환하는 경우 소비자가 여러 가지 오류 사례를 기반으로 다르게 처리하고 다르게해야하는지 스스로 물어야합니다. 두 가지 모델이 있습니다 - 부울을 반환하는 경우 소비자가 사례를 다르게 처리해야하는 경우 다른 정보를 반환해야 할 수도 있습니다. 처리 오류 조건은 문자열 메시지를 기반으로하지 않아야합니다. 예외 유형이나 오류 코드와 같은 구조화 된 데이터가 필요합니다. 업데이트 호출에

    ... 연결 does't이있는 경우

    즉 프로그래밍 오류이기 때문에, 당신은 InvalidOperationException이 던져해야합니다.

    연결 게시 및 interop 오류에서 위에서 설명한 두 패턴으로 돌아갑니다.소비자가 다른 오류 상황을 처리해야하는 경우 bool을 다른 정보와 함께 반환하거나 throw 할 수 있습니다.

    개인적으로 나는 예외가 적게 던져서 프로그래밍 오류 또는 예외적 인 경우로 제한하는 것을 선호합니다. 예를 들어, 비즈니스 규칙을 위반하는 엔티티를 저장하면 예외가 발생합니까? 당신은 그것을 주장 할 수 있습니다.하지만 누군가가 형식을 채우고 코드의 규칙을 충족시키지 않는 예외적 인 것은 아니라고 주장 할 것입니다. 예외적 인 것은 아닙니다.

    좋은 경험 법칙은 break on 예외가있는 디버거를 부착하고 정상적으로 사용할 경우 아무 것도 던져 넣지 않는 것입니다. 그것은 깨끗하게 실행해야합니다.

    여기에 또 다른 SO 예외에 포스트 : 메소드를 호출하는 코드가 이상한 결과를 처리 할 준비가됩니다

    Trying to understand exceptions in C#

    +0

    귀하의 링크가 정말 흥미 롭습니다. 유용하다고 생각했습니다. ** ** 상황에 대해 전혀 생각해 본 적이 없습니다. ** ** 내가 잡아야합니다. –

    관련 문제