Exception은 OCP(Open Closed Principle, 개방 폐쇄의 원칙)를 위배한다.
Exception은 크게 Checked Exception과 UnChecked Exception이 존재한다.
Checked Exception은 Exception을 상속 받은 것들이며, try~catch구문을 써주어야 한다. 하지만, UnChecked Exception은 RuntimeException을 상속 받아 명시적으로 try~catch를 해주지 않아도 된다.
Checked Exception은 java.io.FileNotFoundException 같은 경우이고 UnCheck Exception에는 java.lang.ArrayIndexOutOfBoundsException 같은 경우이다.
처음 Checked Exception이라는 개념이 나왔을땐, 개발자들은 굉장히 획기적인 아이디어라 말하며 칭찬했었다. try~catch를 하지 않으면 컴파일도 되지 않아 개발자의 실수를 줄여주곤 했기때문이다. 하지만, 이것도 잠시 시간이 점점 흐르면서 개발자들은 Exception에 대한 안좋은 평을 하기 시작했다.
Exception은 예외처리를 할게 없는 예외 까지 모두 try~catch구문을 써야 함으로 코드가 길어지고 가독성이 떨어진다는 것이다. 이것은 Checked Exception을 UnChecked Exception으로 바꿔 주어서 해결한다.
try{
//Checked Exception 발생
}catch(FileNotFoundException e){
throw new RuntimeException( "message" ); //RuntimeException으로 바꿈
}
이런것들도 문제지만 가장 큰 문제점은 Exception이 OCP(Open Closed Principle, 개방 폐쇄의 원칙)를 위배한다는 것이다.
이게 무슨 말인가 하면, 특정 라이브러리를 사용하여 어떤 기능을 구현하였을때 그 라이브러리에서 정의한 Exception을 사용하게 된다. 그렇기 때문에 그 라이브러리가 바뀌게 되면 Exception또한 바뀌게 되며 이 Exception을 throws한 상위 단계의 코드까지 모두 수정해야 된다는 소리다.
이는 Exception을 추상화 하여 문제를 해결 할 수 있다. 처리 해야 할 예외 코드가 없다면 Checked Exception을 UnChecked Exception으로 Wrapping해주고, 처리 해야 할 예외 코드가 있다면, 자신이 정의한 Exception으로 Wrapping해주면 된다.
try{
//특정 라이브러리를 사용한 구현
}catch(AException aException){ //특정 라이브러리의 예외
throw new ConnectionException(); //개발자가 정의한 Exception
}catch(BException bException){ //특정 라이브러리의 예외
throw new LoginFailException(); //개발자가 정의한 Exception
}
이렇게 되면 특정 라이브러리의 Exception이 바뀐다 하더라도 위의 method를 사용한 상위 클래스들은 전혀 바뀔게 없다. 또한 Exception에 특정 의미를 부여하여, 이 method을 사용하는 사람이 개발자의 예외 의도를 정확하게 파악할 수 있다.