ITEM 48 :: EFFECTIVE C#
안녕하세요, 48번째 시간입니다.
이번 챕터는 강력한 예외 보증을 준수하는 것이 좋다, 입니다. 새로운 단어가 나왔습니다. 예외 보증! 단어만 봐서는 어떤 예외에 대한 보증인지, 예외 상황 그 자체에 대한 보증인지 잘 모르겠지만, 둘 중 하나일 것 같아요!
설명
-
예외에 대한 보증은 이 책에서 3가지, 각 기본 보증, 강력한 보증, 예외 없음 보증으로 정의했다.
-
먼저, 기본 보증이란, 특정 함수 내에서 발생한 예외가 이 함수를 빠져나오더라도 어떤 리소스도 누수되지 않으며, 모든 객체의 상태가 유효한 상태를 유지함을 의미한다. 이는 예외가 발생한 메서드 내에서 Finally 구문이 구현되어 있음을 의미하는 것이기도 하다.
-
다음으로, 강력한 예외 보증은 기본 보증에 더해, 예외 발생시에도 프로그램의 상태가 변경되지 않음을 추가로 보증하는 것을 말한다.
-
마지막으로 예외 없음 보증은 작업이 결코 실패하지 않으며, 따라서 예외가 발생하지 않음을 보증하는 것을 의미한다. 또한 .NET CLR 은 기본 보증을 준수한다.
-
다만, 객체의 상태를 유효하게 보장하는 것은 여전히 개발자의 몫이고 책임이다.
-
대부분의 경우에서 요청한 작업이 온전히 완료되지 못하고 일부만 완료된 경우 응용프로그램을 손상시키는 경우는 굉장히 많다. 다만, 대부분의 이러한 예는 강력한 보증을 준수함으로써 해결할 수 있다고 한다.
-
강력한 보증을 조금 쉽게 풀어보면 예외로 인한 요청으로 인해 작업이 중단되었을 경우 응용프로그램이 작업을 실행하기 전 상태를 유지하는 것을 뜻한다. 즉, 작업이 온전히 완료되거나, 혹은 응용프로그램의 상태가 그대로 유지되거나 둘 중 하나의 경우만 가능해야 하며, 그 중간은 존재하지 않음을 뜻한다.
-
이를 준수하고 싶다면 표준화된 코딩 기법이 따로 존재하진 않으므로 어렵게 느껴질 수 있으나, Effective C#의 각 장에서 나왔던 여러 권고 사항이 강력한 예외 보증을 준수하는 데 도움을 주며, LINQ 쿼리를 사용하면 기본적으로 강력한 예외 보증 요건을 준수하게 되므로, LINQ 쿼리를 이용하는 함수형 프로그래밍 스타일을 사용하는 것도 도움이 된다.
-
또한, 함수형 프로그래밍 스타일을 사용하지 못하는 경우에는, 작업을 시작하기 이전, 작업을 할 데이터에 대한 복사본을 미리 마련해놓고, 작업 도중에 문제가 발생할 경우 그 복사본으로 다시 롤백하는 개념의 방어적 코딩방도 있다. 이는, 작업 도중의 예외는 괜찮지만, 복사본을 통해 이전으로 롤백하는 부분의 예외는 있어서는 안된다.
-
이러한 지침을 쉽게 구현하려면 변경 불가능한 데이터 구조를 사용하는 것이 좋다.
-
또한, 몇몇 경우에는 복사본으로 롤백하는 방법이 좋지 않은 경우가 있는데, 예를 들면 예외가 발생했을 때 응용프로그램이 종료되어야 하는 경우다. 이 경우에는 강력한 예외 보증은 필요하지 않다.
-
예외 없음 보증은 프로그램 전체에 하기에는 문제도 많다. 따라서, 중요한 함수나 로직의 일부분에 사용하는 것이 좋은데, Finalizer 나 Dispose() 같은 역할이 극히 제한된 메서드의 경우 예외 없음 보증이 필요하며 이로인해 방어적인 코딩이 필요하다. 또한 델리게이트의 대상이되는 메서드는 절대로 예외를 발생시키면 안된다. 이로인해 결국, 이벤트를 발생시키는 코드에 대해서는 강력한 예외 보증을 사용할 수 없다는 말이 된다.
결론
결국, 예외가 발생하면 응용프로그램의 제어 흐름이 뒤바뀌어 최악의 경우 무슨 일이 발생했는지도 알기 어려울 뿐만 아니라, 무엇이 제대로 수행되고 안되었는지에 대한 구분조차 모호해진다. 따라서 강력한 예외 보증을 준수하는 것이 좋다. 마지막으로 참조 타입의 값을 교환해야 하는 상황에서는 더욱 신중하게 코드를 작성해야 한다. 이로 인해 발견하기 어려운 버그가 발생할 수 있으므로!