C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
분야별 포럼
C++빌더
델파이
파이어몽키
C/C++
프리파스칼
파이어버드
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

자유게시판
세상 살아가는 이야기들을 나누는 사랑방입니다.
[9194] Re:예외 처리 어느때 쓰시나요?
박지훈.임프 [cbuilder] 1683 읽음    2004-04-19 01:48
저도 그런 방식의 예외 방법을 쓰지요. 여러 단계의 함수들에서부터 에러 상황을 관리하기 위해서죠.
조금 더 생각해보시면, 프로젝트 전체에서 예외를 체계적으로 발생시키고 관리할 필요가 있을 수 있다는
생각도 드실 겁니다. 그래서 예외의 종류들을 정형화시키고, 그리고 그 예외들을 처리할 루틴들을 다시
정형화시키고...

사실 저도 코딩을 계속 해오면서 어느 순간순간에 개선의 방식으로 떠올려서 해봤던 건데, 여러번 하면서
방식을 계속 나름대로 개선하다보니, 결과적으로는 VCL에서 예외를 다루는 방식과 거의 동일해지더군요.

사실 대부분의 개발자들은 이미 완성된 클래스 라이브러리를 기초로 해서 작업을 하다보니, 예외를 단순히
코딩 에러이고 이 라이브러리를 사용하는 내 잘못으로 예외가 발생했다는 수동적인 관점에서 예외를 바라보게
되는 경향이 있죠. 초보자일 때부터 예외들에 당하는 입장이다보니 피해의식이라고도 할 수 있겠고요.

조금 더 적극적으로 바라보면 예외는 절대로 에러(주로 논리적 에러) 그 자체가 아니죠. 예외는 여러가지
이유에 의해 발생될 수 있고 그 원인 중의 하나가 논리적인 에러 상황이겠구요.
예외가 에러와는 다르다는 측면에서 예외를 본질적인 성격을 생각해보면, 아마도 이쯤 되겠죠.
이유가 있어서 로직 실행이 중단된다.

다시 말해서 예외를 이렇게 정의할 수 있겠습니다. 이유가 있는 실행이 중단되었다는 통보. 여기서 '이유'에
따라 각각의 예외 클래스들이 나뉘어지는 거고요. 그리고 그 중단된 사실의 통보가 각각의 '이유'에 따라
어떻게 처리되어야 하는지는 말 그대로 그 예외를 처리하는 루틴에서 별도의 로직으로 판단하게 되는 거고요.

제 개인적인 관점에서 보면, 아마도 개발자가 예외의 숨겨진 효용성을 깨달을 때의 충격은, C언어의 구조적
프로그래밍 기법에 익숙해졌던 사람이 C++의 객체지향이라는 개념의 기술적 효용성을 깨닫고 받는 충격과
비슷할 겁니다.

보통 개발의 초기 단계에서 애플리케이션을 설계할 때 어떤 설계방법을 쓰든지 관계없이 데이터의 흐름이나
모듈들의 관계 및 순서 등을 우선적으로 따지지 않습니까. 그런데 그런 관점에서 봤을 때, 예외의 발생과
처리 방식도 또 하나의 중요한 기준으로 취급되어야 할 중요성이 있다고 봅니다.
뭐 사실 저도 그렇게 체계적으로 설계를 하는 편이 아니라서 좀 부끄럽기는 합니다만.

제 경험으로 생각해보면, 프로젝트가 복잡해지고 대형화될수록 잘 정의된 예외발생/예외처리 구조는 전체
프로그램의 로직을 더 많이 단순화시켜줍니다. 물론 코드도 적어지고 읽기도 훨씬 편합니다.

가장 간단하면서도 가장 흔한 예를 한가지 들어보죵.
보통 어떤 입력을 받을 때, 예를 들어 로그인 윈도우라면 아이디와 패스워드를 입력받지 않습니까?
이런 경우 일반적으로 서버에 그 데이터(아뒤/패스)를 전송하기 전에 기본적인 유효성 체크를 하게 마련인데요.

이런 경우에 ShowMessage()나 MessageDlg() 같은 메시지박스 함수를 써서 결과를 보여주고 return을 하죠.
그런데 이런 윈도우가 한두개가 아닐 경우라면, 예를 들어 SI성의 프로그램이라면 화면 번호가 있는 수백-
수천개 단위의 화면들로 구성되는데, 보통은 그 화면들 중 적어도 20% 정도 이상은 입력 전용 화면이죠.

이런 경우에 그냥 예외를 발생시키는 편이 훨씬 간략해지고 처리방법도 더 잘 통합됩니다.
Exceptiopn 클래스로부터 상속받은 예외 클래스를 EInvalidInput이라고 만들어놓으면, 다음과 같은 루틴을,
if(!유효검사함수())
{
    ShowMessage(Edit1.Name + " 입력이 잘못되었습니다.");
    return;
}

이렇게 바꿀 수 있습니다.
if(!유효검사함수())
    throw EInvalidInput(Edit1.Name);
(델파이라면 raise EInvalidInput.Create(Edit1.Name); 이렇게 되죠)

그리고 Application->OnException 이벤트 핸들러를 만들어주고, 거기서 다음과 같이 예외를 처리합니다.
if(dynamic_cast<EInvalidInput *>(E) != NULL)
  ShowMessage(((EInvalidInput *)(E))->Message + " 입력이 잘못되었습니다.");

이렇게 하면 일단 유효성 처리의 코드들이 모두 통합됩니다. 그리고 모든 입력 화면에서 유효성 처리가
통과되지 않았을 경우 나타날 메시지나 다이얼로그를 통합적으로 관리할 수 있게 되기도 하고요.
또 조해진님이 말씀하신 것처럼, 함수가 몇단계로 호출된 경우에도 호출된 순서대로 에러 상황을 줄줄이
전달해줄 필요가 없이 단번에 처리가 끝나죠.

뭐 예외를 잘 사용하면 여러 장점이 있지만, 딱 한가지, 단점까지는 아니지만 번거로운 점이 있죠.
잘 아시겠지만 예외를 발생시키면 IDE 내에서 디버깅 모드로 실행시킨 경우 예외를 발생시킨 순간에 IDE로
돌아와서 메시지박스가 떠버리니까, 디버깅할 때 좀 짜증나죠.

그리고 참고로... 조해진님이 말씀하신 중에, 예외를 사용하면 오버헤드가 증가된다고 하셨는데요,
전 실행에 어떤 오버헤드가 있을지는 모릅니다만, 예외 자체가 현재까지 실행되고 있는 루틴을 중단시키는
것이니 오버헤드가 얼마나 크든지 전혀 고려할 상황이 아닌 거 같은데용. 아마 측정도 힘들 듯. ^^


조해진 님이 쓰신 글 :
: 일반적으로 제공해 주는 언어의 예외 처리기능을
:

:
: "도데체 어디다  쓰나?"  라는 생각을 해왔습니다
:

:

:
: 또한 함수의 리턴값 만으로 충분히 예외 상황을 처리할수 있다고 생각해 오면서 
:

:
: "예외 처리 기능을 쓰는건 불필요한 오버헤드만 증가 시킬뿐이다"  라고  자위하고 있었습니다
:

:

:
: 하지만......  불가피하게  함수의 함수 속 깊숙이 들어가  에러를 리턴 받으려면
:

:
: 받아오는 절차가 함수 깊이 만큼 되더랍니다 -_-;
:

:

:
: 이렇게 프로그래밍 하면 안되겠다 싶어서  함수의 함수 깊은속 까지 들어가 에러값을 받아오는 경우라면
:

:
: 예외를 발생 시키는 편이 좋을거 같다는 생각이 들더군요
:

:
: 이거 심각하게 고민하다가 갑자기 떠오르는 방안이었습니다
:

:

:
: exceptional c++ 책에보면  예외 처리를 생각한 구조라면 설계때부터  그런식으로 만들어야 한다고 하더군요
:

:
: 맞는 말 같기도 한데.....   언어의 예외처리기능, 볼랜드 회원님들은 어떤식으로 사용하는지 궁금하네요
:
:
조해진 [mastercho]   2004-04-19 03:18 X
More Effective C++ 에서는  예외처리 인 try catch 루틴을 넣기만 해도

그거에 사용되는 보이지 않는 루틴이 상당하다고 합니다

그래서 예외가 발생될 이유가 없는 곳에는 try 자체를 쓰지 않는게 좋다고 하더라고요

조해진 [mastercho]   2004-04-19 03:28 X
그리고  마지막에 말씀 하신 예외는 ^^; 정말 예외 상황이고요
중단될만한 예외를 가지고 한다기 보단 소켓 send 실패시 예외 발생이었습니다.

그리고  More Effective c++에서는   일어날 가능성이 희박한 치명적인 예외라면  오버헤드가  없다고 봐도 된다고 하더군요
왜냐하면 정말 일어날지 안일어날지 모르기 때문이고 가능성도 거의 없기 때문입니다
이런것을 일반적인 성능 알고리즘에 넣으면 오버헤드가 거의 0 이 됩니다 :)

사실 ACE라는 프레임웍에서는 new로 인한 일관성있는 예외 처리를 위해
무조건 new 실패시 리턴값을 0으로 받겠끔 구조를 맞춘것을 보았습니다

예외라는건 일반적으로 생각되지 않는 결과를 가져올때 쓰이는 방법인데
사실 제 요지는 ....
try catch 구조을  if 을 이용한 리턴 결과를 사용 방법 대신  어떻게
좀더 유용하게 쓰일수 있을까라는 고민이 더 맞을듯 싶기도 하네요


박지훈.임프 [cbuilder]   2004-04-19 04:59 X
제가 공부를 잘 안하는 편이라, 조해진님이 말씀하시는 요지가 제가 리플을 단 것보다 고차원적인 문제일 수도 있다는 생각이 드네요. 전 조해진님께서 단순히 여러 단계의 함수들을 빠져나가기 위해 예외를 발생시키는 경우를 '일반적인' 예외 발생과 구별해서 생각하신 것 같다고 추측한 거였거든요. 전 그렇게 구분하는 것이 별 의미가 없다고 생각하고요.

예외 처리를 설명하는 책들을 보면 '예외가 발생할 것 같은 루틴에서 try를 걸고 감시한다'고 설명하던데, 예외 처리를 그런 쪽으로만 보는 관점이 수동적인 관점이라고 말한 거고요. 예외의 기본 속성이 해당 예외의 처리 루틴을 만날 때까지 함수들을 계속 빠져나가는 것이기 때문에, 그런 효과를 기대하고 코딩하는 것은 당연히 자연스럽고요, 나아가서 혹은 예외처리를 하나로 통합시킬 수 있다고 한 겁니다. (예외를 통합 처리 하려면 VCL에서처럼 애플리케이션 전역적인 예외처리 루틴이 필요하겠죠) 실제로 그렇게 사용하고 있구요. 전 예외를 아주 즐겨 발생시키는 편입니다.

예를 든 코드는 물론 '정말' 예외 상황입니다만, 모든 예외를 통합적으로 관리하는 예를 말씀드린 거구요. 말씀하신 오버헤드에 대해서는, 예외 처리 루틴(try 블럭)의 오버헤드는 VCL에서는 전혀 신경쓰지 않을 수 있겠죠. try 블럭은 VCL 내부에 이미 있으니까요. 맘만 먹으면 try를 단 한번도 코딩하지 않고도 예외처리를 다 할 수 있겠죠.

혹 제가 졸다가 봉창을 두들기지 않았나 하는 생각이... 그렇다면 알려주세용~ ^^;;

+ -

관련 글 리스트
9193 예외 처리 어느때 쓰시나요? 조해진 1061 2004/04/18
9208     Re:예외 처리 어느때 쓰시나요? 홍환민.행복 1282 2004/04/20
9194     Re:예외 처리 어느때 쓰시나요? 박지훈.임프 1683 2004/04/19
9200         예외 처리 어느때 쓰시나요? -> 배우는 사람의 입장에서의 예외처리. SteelHeart 1142 2004/04/19
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.