2011-01-04 4 views
1

3 단계 앱 프론트 엔드 도메인 및 데이터 액세스가 있다고 가정 해 보겠습니다. 나는 호출 스택에서 높은 예외를 포착하는 것이 좋습니다 읽었 ... 그래서 한 나는 데이터 액세스 예외가 발생하는 경우, 도메인 층은 단지 마지막으로, 그래서n 계층을 처리 할 때 호출 스택에서 예외를 catch하십시오.

시도 {

같은 않습니다 } finally { //}

을 정리하고 데이터 액세스 예외를 프런트 엔드 계층으로 통과시킵니다. 프론트 엔드 레이어를 내장으로 처리하여 레이어링을 중단하지 않습니까? 나는 각 레이어가 핸들러 또는 래핑을해야하고 예외를 던져서 호출 레이어를 처리 할 수 ​​없다고 생각한다. 어떤 생각?

답변

1

지금까지 좋은 의견이 많이 있었으므로 알려 드리겠습니다.

규칙 # 1. 실제로 처리 할 예외 만 잡습니다. 핸들은 클라이언트의 요청을 계속할 수있는 방식으로 처리한다는 의미입니다. 정보를 기록하기에 충분히 길게 잡을 수 있습니다 (악용하지 마세요. 일반적으로 스택은 충분한 정보입니다). 또는 전파하기 쉬운 다른 오류 (Ala Runtime based)로 변환하십시오. 그러나 당신이 그것을 다룰 수 없다면, 그것을 잡는 것을 괴롭히지 마십시오. 그것은 쓸모없고 혼란스러운 추가 코드 일뿐입니다. 당신이 기록하거나 개조 할 때에도, 당신은 재위 재가 끝납니다.

대부분의 시간을 실현하면 예외를 처리 할 수 ​​없습니다. 진실로. 많은 사람들이 이것을 파악하지 못합니다. 하지만 실제로는 디스크에 읽기 또는 쓰기 IOException이 발생하면 게임이 끝난 것입니다. 해당 요청은 사용자에게 완료 될 수 없습니다. 네트워크가 불안정하고 데이터베이스와 통신 할 수없는 경우에도 마찬가지입니다.

규칙 # 2. 처리 할 수없는 예외가 발생하면 수행 할 수있는 유일한 방법은 사용자에게 도움이되는 방식으로 실패를 시도하는 것입니다. 즉, 나중에 분석 (원본 스택/원인 포함)을 위해 기록한 다음 최대한 유용한 정보를 사용자에게보고하십시오. 시스템을 일관된 상태로 유지하기 위해 필요한 것을 정리하십시오.

최종 사용자와의 이러한 통신이 매우 높은 수준에서 발생하면 보통 그 수준을 파악해야합니다. 대부분의 경우, 시작 지점과 사용자에게 로깅 및보고를 위해 catch하는 최상위 수준 사이의 예외 처리에는 거의 가치가 없다는 것을 알게되었습니다. 나는 종종 RuntimeException 형식으로 변환하지만 레이어를 통한 전달을 쉽게하기 위해서만 수행됩니다.

가장 중요한 점은 일반적으로 예외를 처리 할 수 ​​없다는 것을 인식하는 것입니다. 따라서 예외를 작성할 수있는 코드는 가능한 한 간단해야합니다.

+0

스트림에서 문서를 deserialize하려고 할 때 예외가 발생한다고 가정하십시오. 부분적으로 구성된 문서를 포기하고 파일을로드 할 수 없다는 사실을 사용자에게 알리는 경우 예외를 처리해야합니까? – supercat

+0

@supercat - 예. 합리적으로 할 수있는만큼. 무엇이 잘못되었는지와 같은 좋은 오류 메시지를 제공 할 수 있습니다. 그러나 문서를 deserialize하지 못하면 더 이상 무엇을 할 수 있습니까? – rfeak

+0

버려진 문서 이외의 상태를 손상시키지 않는 예외와 손상된 시스템 상태를 나타내는 예외의 차이점을 알려면 어떻게해야합니까? – supercat

0

필자는 겹겹이 만들어내는 것이 이러한 순수한 아이디어라고 생각하지 않습니다.

포장 및 재사용으로 많은 가치가 추가되지 않습니다.

서비스 레이어에서 예외를 처리하는 것이 잘못된 이유는 무엇입니까? 그것은 방어선의 마지막 라인 인 라인의 끝이되어야합니다. 이 디자인을 사용하면 서비스 로그에 예외를 기록 할 수 있으며 사용자 친화적 인 메시지를 UI에 보내 표시 할 수 있습니다.

+0

서비스 레이어라고 할 때 프론트 엔드 레이어라고 생각합니까? 그 아래의 레이어에서 처리해야하는 정보가 필요할 수있는 코드로 라인 레이어의 상단을 혼란스럽게하지 않습니까? 예를 들면 : 어떤 이유로 든 데이터 액세스 호출을 포기하기 전에 3 번 호출하고, 그 상태가 방금 전달 된 계층에 저장되는 경우, 프론트 엔드 계층은이를 어떻게 액세스합니까? 최상위 레이어를 부피가 커 보이지 않을까? 이 패턴을 따르는 예제 코드가 있습니까? – treefrog

+0

"프론트 엔드"가 아니기 때문에 "서비스"는 프레젠테이션 또는 내게보기라는 의미입니다. 정의에 따르면, 그것이 거품을 내면, 아래의 레이어가 그것을 처리 할 수 ​​없다는 것을 의미합니다. "핸들"은 스택 추적을 기록하는 것을 의미하지 않습니다. 이는 드물거나 예외적 인 상황에 대해 무언가를하는 것을 의미합니다. 어떤 주를 의미합니까? SQL 예외가 발생하면 SQL 오류 코드 외에도 그 밖에 무엇이 필요합니까? 필요한 경우 사용자 정의 예외에 추가하십시오. 나는 그것이 아무것도 부피가 크다고 생각하지 않는다. 샘플 코드 없음. – duffymo

+0

레이어의 이름을 혼동하지 않도록합니다. 나는 "프론트 엔드 도메인 및 db 계층"이라고 말했고 "서비스"로 회신했는데 내 목록에 무엇을 언급했는지 몰랐습니다. 그래서 Layer1 - layer n (가장 안쪽)을 말할 것입니다. 여기서 다루는 것은 3 번 재 시도한다는 것을 의미합니다. 어딘가에는 어딘가에 저장해야합니다 - 어디에서 exceptioin이 발생했는지, 가장 가까운 곳에 있어야합니다. 레이어 n-1 위에 있습니다. (계속 ... 다음 주석에) – treefrog

0

일반적으로 호출 스택에서 더 높은 예외를 catch하고 싶지만 그 의미가있는 지점까지만 catch하려고합니다. 데이터 수준에서 예외를 처리하고 로그하고 프런트 엔드에 메시지를 전달하면 상황이 간단하고 유연 해집니다.

개인적으로 내가 시도하고 마지막으로해야 할 경우 호출자에게 전달하기보다는 상황에 대한 정보를 얻고 싶습니다. 좋은 디자인 규칙 (일반적으로 KISS와 같은 다른 규칙)에는 항상 예외가 있다는 것을 명심하십시오.

0

여기에는 세 가지 연동 문제가 있습니다.

먼저 지속적으로 예외를 다시 래핑 할 수 있지만 제공하는 가치는 무엇입니까? 원래 예외에 대해 더 많은 레이어를 만들었을뿐입니다. 예외에 대한 추가 정보를 제공 할 수 있거나 첫 번째 예외로 인해 다른 예외가 발생할 경우에만 예외를 래핑합니다.

둘째, 예외적 인 생각은 함수를 정상적으로 완료 할 수 없다는 응답입니다. 문제를 다루는 것이 가장 합당한 장소에서 예외를 잡아야합니다. 코드에 "다른 대안"이있는 경우 예외가 해당 시점에 트랩되어야합니다. 그렇지 않으면 사용자 또는 개발자가 작업하도록 로그에 기록하십시오.

세 번째로 try/finally 블록입니다. 이러한 기능은 예외로 인해 리소스가 열린 상태 또는 할당 된 상태로 중단 될 때 유용합니다. 나는 항상 try/finally를 사용하여 열어 둘 수있는 리소스를 정리합니다 (필자가 가장 좋아하는 것은 java.sql의 Statement/ResultSet, 거대한 메모리 돼지입니다). 정말 훌륭한 프로그래머라면 엄청난 메모리 누출이나 리소스 제약없이 정상적으로 복구 할 수있는 방법으로 코드에이 점이 많을 것입니다.

관련 문제