제가 생각하는 try-catch문의 스타일이 두가지가있습니다.
둘다 장단점이있어서,
(1) 어느게 좋은지 나쁜지의 문제라서 어느한쪽을 지양해야하는 문제인지,
(2) 개발자의 코딩스타일이니 어느걸 써도 상관없는 문제인지,
궁금합니다.
개인프로젝트 3개를 진행해보면서 두가지 다 써봤지만,
여전히 해결되지않네요...
주제 : try-catch문을 분리해야할까 아닐까... 에요.
try
{
//InvalidStringException이 발생할 가능성이 있는 코드
}catch(InvalidStringException e)
{
}
try
{
//NulberFormatException이 발생할 가능성이 있는 코드
}catch(NumberFormatException e)
{
}
try
{
//InvalidStringException이 발생할 가능성이 있는 코드
//NulberFormatException이 발생할 가능성이 있는 코드
}catch(InvalidStringException e)
{
}catch(NumberFormatException e)
{
}
고민1.
try문에는, 해당 예외가 발생할 가능성이 있는 코드 위주로 오는게 좋다는 생각이에요.
try문에 코드가 200줄이 있는대,
그중 딱 한줄만 NumberFormatException이 발생할 가능성이 있다면,
나머지 199줄까지 try문에 때려박아야 할까? 에요.
메소드는, 하나의 기능만 해야한다는 원칙에 의거하여
아무리 코드를 분리하더라도,
하나의 메소드 안에 RuntimeException까지 포함하면
발생할 수 있는 예외가짓수가 2개이상이 넘는경우가 많아요.
그런경우, catch문을 보면서,
try문의 어느라인에 어떤 예외가 발생할 수 있는지 빠르게 캐치할 수 있어야하는대..
상황 : AException이 try문의 어느라인에서 발생할 가능성이 있는지 찾아야함
try문안에...
(1) 전혀 예외가 발생하지않는 코드
(2) BException이 발생할 가능성이 있는 코드
(3) AException이 발생할 가능성이 있는 코드
C D E 이렇게 죄다 있다면.....?
또한 그게, 예외끼리 상속관계가 전혀 맞지않는 아예 다른 주제의 예외라면...?
어우야...
결론1 >> try문 하나에 다 넣는 코딩은 나중에 읽는데 시간이 오래걸립니다.
ㅡㅡㅡ
그렇다고해서 분리하는게 마냥 장점만 있지 않습니다.
public static void buy(int code, int money)
{
try
{
//물건을 사기위한 굉장히 긴 코드
// 돈이 없음
}catch(NoMoneyException e)
{
// 해당 제품번호의 물건 없음
}catch(ProductNotDefException e)
{
}
}
여기서 주목해주셔야할건, try-catch문만 벗어나면 메소드가 종료된다는 부분입니다.
코드 실행흐름을 저것과 동일하게 하면서 try-catch문을 분리하려면,
public static void buy(int code, int money)
{
// 두개의 try문에서 사용해야하는 변수
int var = 0;
try
{
var = 100;
}catch(NoMoneyException e)
{
// 예외처리
return;
}
try
{
var = 20;
}catch(ProductNotDefException e)
{
// 예외처리
return;
}
}
이렇게 각 catch문에서 return을 해야합니다.
하나의 try문으로 이루어져있으면 어떤 예외가발생해도 메소드가 종료되지만,
두개의 try문으로 이루어져있다면 catch문에서 return을 해줘야 종료되기 때문입니다.
또한, try문이 두개이기 때문에, 각각 try문에서 모두 사용되는 변수를
try문 바깥에서 미리 선언하고 가야합니다.
변수를 미리 선언하고, return을 꼬박꼬박 걸어야 해서
코드가 더러워집니다.
결론2 >> try-catch문을 여러개로 분리하면, 코드가 더러워지는 경향이 있습니다.
저는 일단 코드가 좀 길어지는걸 감수하고,
try문의 어느라인에 어떤 예외가 발생하는지를 빠르게 파악하는게 좋아서
@RequestMapping(value = "/answerForm.do")
public ModelAndView answerForm(HttpServletRequest request, HttpServletResponse response)
{
ModelAndView modelAndView = new ModelAndView();
HttpSession session = request.getSession();
UserDto userDto = (UserDto)session.getAttribute("userDto");
int inquiryCode = 0;
try
{
inquiryCode = Integer.parseInt(request.getParameter("inquiryCode"));
}catch(NumberFormatException e)
{
httpErrorService.setError500Page(modelAndView, "errorMessage", e.getMessage());
return modelAndView;
}
try
{
if(userDto == null)
{
userDto = rememberMeService.getRememberMeUserDto(request.getCookies());
if(userDto == null)
{
modelAndView.setViewName("redirect:" + LoginController.REDIRECT_JSP_LOGIN_FORM_PATH + "?previousPage=" + DO_ANSWER_FORM + "?inquiryCode=" + inquiryCode);
return modelAndView;
}
}
}catch(CookieManipulatedException e)
{
httpErrorService.setError500Page(modelAndView);
modelAndView.addObject("errorMessage", e.getMessage());
return modelAndView;
}
이렇게 분리했었습니다.