새로운 프로그래머를위한 예외 처리를 가르치는 방법? [닫은]


21

프로그래머에게 예외 처리를 가르치는 방법은 무엇입니까? Data Structures, ASP.NET, WinForms, WPF, WCF 등 모든 것을 쉽게 배울 수 있습니다.

예외 처리를 통해 try-catch-finally를 가르치는 것은 예외 처리의 구문 적 특성 일뿐입니다.

그러나 무엇을 가르쳐야 하는가-코드의 어떤 부분을 try 블록에 넣 습니까? 캐치 블록 에서 무엇을합니까 ?

예를 들어 설명해 드리겠습니다.

Windows Forms 프로젝트 (작은 유틸리티)를 작업 중이며 3 가지 프로젝트로 아래와 같이 설계했습니다.

  1. UILayer
  2. 비즈니스 레이어
  3. 데이터 레이어

DataLayer (UILayer는 BusinessLayer를 호출하고 차례로 DataLayer를 호출 함)에서 Exception (XDocument를로드한다고하자 예외를 발생시킵니다)이 발생하면 다음을 수행합니까?

//In DataLayer
try {
    XDocument xd_XmlDocument = XDocument.Load("systems.xml");
} 
catch(Exception ex)
{
    throw ex;
}

어떤 것이 BusinessLayer에서 다시 발생하고 UILayer에서 포착되어 로그 파일에 기록됩니까?

이것이 예외 처리에 관한 방법입니까?


15
당신 그렇게하려고 한다면 , 잡기를 원하지 않습니다. (Exception ex) {throw ex; }-대신에 {throw; }
Steven Evers

4
finally 블록을 잊어 버리지 않습니까?
Chris

1
태그에 언어를 지정해야합니다. 대부분의 예외 구현에 공통적 인 것보다 더 자세하게 설명하고 블록 외부의 것을 무시합니다. 예를 들어 C ++에서 예외 처리의 가장 중요한 부분은 예외 안전 프로그램을 작성하는 방법을 아는 것입니다.
David Thornley


"예외"를 잡는 것은 나쁜 생각이라는 것을 알고 있기를 바랍니다. 특정 예외를 포착하고 그에 따라 처리하려면 예외를 던지는 것이 아니라 중첩 된 catch 블록이 있어야합니다.
minusSeven

답변:


29

예외 처리를 설명하려면 그 개념을 설명하십시오 . 오류가 자주 발생하는 코드는 해당 오류를 올바르게 처리하는 방법을 모릅니다. 올바르게 처리하는 방법을 알고있는 코드는 해당 함수를 호출 한 함수일 수도 있고, 더 많은 호출 스택 일 수도 있습니다.

예외를 발생시킬 수있는 루틴을 호출하는 루틴을 작성할 때 해당 오류를 올바르게 처리하는 방법을 알고 있으면 호출을 try 블록에 넣고 오류 처리 코드를 catch 블록에 넣으십시오. 그렇지 않은 경우에는 그대로두고 호출 스택에서 위에있는 것이 오류를 처리하도록하십시오.

"캐치 예는 던져 전"입니다 말하는 되지 실제로 아무것도 처리하지 않기 때문에, 예외 처리를 할 수있는 좋은 방법입니다. 또한 언어의 예외 모델이 작동하는 방식에 따라 문제를 디버깅하는 데 사용할 수있는 스택 추적 정보를 지우면 실제로 유해 할 수 있습니다. 처리 방법을 알고있는 루틴에 도달 할 때까지 예외가 호출 스택을 전파하도록하십시오.


4
"... 실제로 아무것도 처리하지 않기 때문에"+1 + 예외 처리를 처음 접하는 사람들은 종종 포착이 처리를 의미한다고 생각하고 문제를 해결하기 위해 무언가를 하지 않으면 예외 처리 가 아니라고 생각합니다 . 그냥 코드 팽창입니다.
Jimmy Hoffa

13

대부분의 경우와 마찬가지로 예외 및 예외 처리는 외관상 단순한 솔루션 (C 스타일 리턴 코드 및 errno)이 왜 그렇게 작동하지 않는지를 보여줄 때까지 새로운 프로그래머에게 문제를 찾는 솔루션처럼 보일 수 있습니다. 나는 문제를 동기 부여하고 상황에 맞게 시작합니다. 리턴 코드 또는 전역 / 정적 변수를 사용하여 오류 처리 방법을 보여줍니다. 그런 다음 왜 잘 작동하지 않는지 예를 들어보십시오. 그리고 오직 다음, 예외를 소개하고 그들이 대역 신호의 한 형태임을 설명하고 있음 요점은 당신이 무시하면 예외가 누군가에게 호출 스택까지 책임을 전가하는 기본 동작이다 사람 수 처리해.

결론 : C에서 오류 처리가 어떻게 수행되었는지를 보여 주면 학생들이 실제로 예외가 무엇인지 이해하고 실제로 처리 할 수없는 예외를 포착하는 것이 기본적으로 암흑 시대에서 일이 수행되는 방식을 시뮬레이션하는 것입니다.


2
전통적인 C 스타일 리턴 코드 및 오류 번호에서 이들을 이끌고 제대로 작동하지 않음을 보여 주므로 작동 방식을 가르치는 것은 +1입니다!
카니 니

3
@ Kanini : 일반적으로 가장 상대적으로 새롭고 높은 수준의 구성은 문제를 찾는 솔루션처럼 보이며 어떤 문제를 해결하고 왜 발명했는지 이해하지 못하면 잘못 사용하기 쉽다고 생각합니다.
dsimcha

예외없이 수행하는 방법을 보여주는 것이 좋지만, 예외를 사용할 때와 다른 기술을 사용할 때를 설명해야하는 부담이 온다는 데 동의합니다 (모든 상황이 예외적이지 않기 때문에)
Matthieu M.

@ Matthieu : 맞습니다. 그러나 예외적으로 해결해야 할 역사적 문제가 무엇인지 이해한다면, 예외가 아닌 상황에서는 예외를 사용하는 것이 어리석은 일입니다.
dsimcha

그렇기 때문에 내 +1을 얻습니다. 방금 당신의 대답이 "다른 메커니즘을 사용하지 마십시오"로 해석 될 수 있다고 느꼈습니다 :)
Matthieu M.

5

예외에 대한 설계 지침으로 시작하고 DO, DO NOT 및 AVOID를 포함합니다. 또한 그 이유도 제시합니다.

귀하의 예에서 관련 섹션은 래핑 예외입니다.

그리고 이런 식으로 쓰여질 것으로 기대합니다. 특정 예외를 포착하고보다 의미있는 메시지가 전달되도록 정보를 추가하려고 시도합니다. 또한 내부 예외는 여전히 로깅 목적으로 유지됩니다.

//In DataLayer

try
{
XDocument xd_XmlDocument = XDocument.Load("systems.xml");
}
catch(FileNotFoundException ex)
{
        throw new TransactionFileMissingException(
                     "Cannot Access System Information",ex);
}

UPDATE Kanini는 데이터 레이어에이 예외 블록이 있거나 파일 검사가 Business Layer에서 사용 가능한지 확인하는 것이 좋습니다.

우선 Wrapping Exceptions의 이론적 근거는 이것입니다.

하위 계층 예외가 상위 계층 작업의 맥락에서 의미가없는 경우 하위 계층에서 발생한 특정 예외를 더 적절한 예외로 래핑하는 것이 좋습니다.

따라서 상위 계층이 파일에 대해 알아야한다고 생각되면 데이터 계층은 다음과 같아야합니다

//In DataLayer

XDocument xd_XmlDocument = XDocument.Load("systems.xml");

캐치하지 마십시오.

개인적으로 데이터 레이어가 어셈블리 리소스 인 기본 systems.xml을 사용하는 것과 같은 유용한 작업을 수행 할 수 없다면 아무것도 기록하지 않거나 예외를 줄 바꿈하는 것이 좋습니다. 로깅은 어떤 방법과 파일이 문제인지 알려줄 것입니다. ( throw ex이 경우 또는 기본 설정 throw도 수행하지만 값을 추가하지 않음). 즉, 일단 식별되면 문제를 신속하게 해결할 수 있습니다.

이 특정 예제와 마찬가지로 XDocument.Load에서 다음과 같은 문제가 발생하여 네 가지 예외가 발생할 수 있습니다.

  • ArgumentNullException
  • SecurityException
  • FileNotFoundException
  • UriFormatException

다음 코드가 존재하지 않고 FileNotFoundException이 발생하지 않는다는 것을 안전하게 보장 할 수는 없습니다. 단순히 존재 확인을 수행하고로드 할 때 사라질 수 있기 때문입니다. 비즈니스 계층에서 사용할 수 있으면 도움이되지 않습니다.

 if (File.Exists("systems.xml")) 
     XDocument.Load("systems.xml");

다른 프로세스가 독점적 인 파일 잠금을 가지고있는 경우이 예외가 발생하는 이유는 File.CanIOpenThis () 메소드가 없기 때문에 읽기 위해 파일을 열려고 시도 할 때까지는 오류가 발생하지 않기 때문에 SecurityException이 더욱 악화됩니다. 그리고 그러한 방법이 존재하면 여전히 File과 동일한 문제가 있습니다.


수정 : 감사합니다! 그러나 데이터 레이어에서이 예외 블록을 갖는 것이 옳습니까? 파일이 사용 가능한지 아닌지 비즈니스 계층에 없는지 확인하는 것이 전부입니까? 그렇지 않으면 코드 작성 방법에 동의합니다.
Kanini

수정 : 내 모국어에서 카니 니는 컴퓨터를 의미하지만 카니는 과일을 의미합니다 ;-)

내 실수로 화가 났다고 말할 수는 있지만 매우 죄송합니다.
콘래드 프릭스

1
수정 : 화가? 전혀. 크게 즐거웠다. 내 동생은 내가 그에게 이것을 지적한 이후로 웃음을 멈추지 않았습니다. 왜냐하면 이상한 모양을 제외하고는 어쨌든 과일을 닮지 않았기 때문입니다.
Kanini

4

역할극을 할 수 있습니다. (이것은 농담 게시물이 아닙니다)

콜 체인을 수행하는 워크숍을 수행해야합니다. 각 사람은 대상입니다. 초보자와 "게임"의 도움을 이해하는 사람들이 필요합니다.

파일 IO와 같은 매우 간단한 문제를 사용하십시오. gui-> 모델-> file_io

파일 리더 인 사람은 다음 사람에게 말해야합니다 ....

먼저 리턴 코드로 수행하십시오. (포스트잇 메모 사용?)

상호 작용이 단지 "코드가 말한 것"이라면 사람들에게 예외가 예외라는 것을 깨닫게 할 수 있습니다.

리턴 코드의 경우 포스트잇 메모를 전달하십시오.

예외적으로, 손을 공중에 던지고 문제가 무엇인지 말하십시오.

그런 다음 "catch x, throw x"를 수행하고 GUI가 "모델에 예외가 있음"이라는 진단이 훨씬 나빠지는 것을 확인하십시오.

사람들이 다른 사람들과의 상호 작용을 아주 잘 이해하기 때문에 이것이 사람들을 훈련시키는 데 효과적이라고 생각합니다.


역할극 아이디어에 +1. 우리는 이전에 그것을 생각하지 않았습니다. Role Play를 통해 프로그래밍 프로그래밍을 가르치는 사람은 누구입니까?
카니 니

1

예를 들어 클래스의 자식 / 부모 관계를 이해해야하는 예외를 이해한다고 상상할 수 있습니다. 자녀가 부모로부터 기능을 상속받을 수 있음을 이해하면, 자녀가 문제가있는 경우 처리 할 수없는 문제는 부모가이 문제 (예외)를 부모에게 전달하여 부모가 처리 할 수 ​​있음을 초등학교 수준에서 이해할 수 있습니다 그것으로.

이는 예외 처리 방법을 알고있는 장소가 될 때까지 연결 관계가됩니다.

그리고 마지막 으로이 문제는 사소한 부분입니다 ... 문제가 발생하면 무언가를 처리해야하므로 프로그램이 치명적으로 종료되지 않아야합니다. 예외가 처리 된 후 finally 블록이 있습니다. 시도 캐치에 관계없이 항상 실행됩니다 .

좋은 예는 네트워킹과 관련이 있습니다.

  • 우리는 연결합니다
  • 우리는 그것을 사용하여 연결 괜찮습니다
  • 완료되면 우리는 닫고 무료 자원

또는 예외적 인 경우 :

  • 연결하다
  • 무언가를 처리하는 예외가 발생합니다.
  • 어느 시점에서 우리는 관련된 연결 및 자원을 확보

1

예외 처리가 아주 좋은 초보자에게 응용 프로그램을 제공하십시오. 어딘가에 예외를 던져서 Logs의 도움으로 디버깅하도록하십시오. 예외 전파를 추적하여 예외를 디버깅 할 수 있어야합니다. 이 운동을 3-4 번하십시오. 이제 코드에서 모든 예외 처리를 제거하고 동일한 예외를 추적하도록하십시오.

예외 처리 코드에 대한 감사는 즉시 감사하겠습니다.


계획 같은 소리. 인터넷에서 사용할 수있는 샘플 코드 (예 : sourceforge.net)가 있습니까?
카니 니

0

IMO, 예외 처리 및 흐름 제어문은 기본적으로 동일하다고 생각해야합니다. 현재 상태에 따라 프로그램 흐름을 제어하는 ​​데 사용합니다. 차이점은 예외 처리는 오류 (또는 예외)가 발생할 때만 반응한다는 것입니다.


@ denny : "오류 (또는 예외)가 발생할 때 예외 처리 만 반응합니다"에 동의하지만 "예외 처리 및 흐름 제어 문이 기본적으로 동일하다는"문에 대해서는 확신이 없습니다. 나는 정중하게 동의하지 않습니다. catch 블록은 해당 조건에서 수행해야 할 작업을 인정합니다. 그러나 try 블록은 흐름이나 제어에 관한 것이 아닙니다. finally 블록은 흐름이나 제어에 관한 것이 아닙니다. 어쩌면 나는 당신의 대답을 오해했지만 당신은 나와 다른 사람들의 이익을 분명히 할 수 있습니까?
카니 니

0

아마도 새로운 프로그래머에게는 도움이되지 않지만 함수형 프로그래밍에서 모나드를 사용하기 시작하면 예외 개념을 훨씬 잘 이해한다는 것을 알았습니다. 모나드는 데이터가 프로그램 내외부로 이동할 수있는 모든 "채널"을 고려해야합니다. 모든 데이터는 해당 데이터 흐름의 일부를 "숨기기"위해 편리한 추상화를 제공하기 때문입니다.

함수가 다른 유형의 출력을 가질 수 있으며 예외는 우선 순위가 높은 함수 반환과 같습니다.

대부분의 언어에서 예외가 작동하는 방식 (구현 세부 사항)이 아니라 추상적 의미에서 이것이 일어나고 있음을 이해합니다.


0

원숭이가 키보드를 사용하는 척

원숭이들이 키보 라드에 앉아이 응용 프로그램을 사용하는 척하는 코드를 작성할 때 사람들에게 말했었습니다.

이것은 모든 종류의 것들을 예상하는 방법을 가르쳐주었습니다.

  • 누락 된 데이터
  • 누락 된 파일
  • 숫자를 예상 할 때 영문자
  • 0으로 나누기

나는 원숭이가 열쇠를 두드리고 멋지게 따라가는 것 대신 원하는 것을하는 것의 단어 그림이라고 생각합니다. 그것은 나를 위해 일했다.


원숭이? 귀하의 비즈니스 사용자는들은 적이 없다고 생각합니다. ;-)
Kanini

@ Kanini-좋은 것. 그것은 나의 해병대 시절이었습니다. 오류 트래핑과 관련하여 사람들이 상자 밖에서 생각하기를 원했습니다. 오류 트래핑이라고 말했습니까? 예외 처리를 의미했습니다.
Michael Riley-AKA Gunny
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.