'10.03.23 story JAVA이야기2010. 4. 1. 15:02
실패 원자성을 갖도록 노력하자
어떤 연산 수행 중에 실행 실패가 생겼더라도, 예외를 던진 객체는 여전히 정의가 분명하고 사용가능한 상태로 있는 것이 바람직하다. 호출자가 복구하기로 되어있는 checked메소드에서는 더욱 그렇다. 일반적으로, 호출된 메소드가 실행에 실패하더라도 객체 상태는 메소드 호출전과 똑같아야 한다. 이런 특성을 갖는 메소드를 실패 원자성 메소드라 한다.
이런 효과를 얻는 방법이 몇 가지 있다.
가장 간단한 방법은 불변 객체로 설계하는 것이다. 객체가 불변이면, 실패 원자성하고는 무관하다.
가변 객체를 처리하는 메소드의 경우에 실패 원자성을 성취하는 가장 보편적인 방법은, 연산 수행 전에 매개 변수의 유효성을 검사하는 것이다. 이렇게 하면 객체의 변경이 시작되기 전에 사전 검사에 따라 미리 예외를 던질 수 있다.
실패 원자성을 성취하는 더 좋은 방법은, 객체를 변경하는 코드 부분에 앞서 실패할 수 있는 코드 부분이 실행되도록 연산순서를 조정하는 것이다.
TreeMap에 요소하나를 넣으려고 한다면, 먼저 타입이 맞는지 검사하고 , 타입이 맞다면 데이터를 넣는 작업을 수행할 것이다. 만약 틀리다면, ClassCastException 예외가 발생할 것이다. 트리 구조가 변경되기 전에 요소 검색을 먼저 하면서 예외가 발생한다.
실패 원자성을 성취하는 3번째 방법은 , 연산 도중에 발생하는 실패를 가로채는 복구 코드를 작성하는 것이다.
마지막 방법은, 객체의 임시 복사본을 만들어 연산을 수행하고, 연산이 완전하게 끝나면 그 객체의 내용을 임시 복사본의 내용으로 변경하는 것이다. 일단 데이터가 임시 데이터 구조에 저장되면 연산을 더 빨리 수행할 수 있을 때 이 방법을 사용하면 효과적일 것이다.
Collection.sort메소드에서는 입력으로 받은 List의 요소들을 정렬에 앞서 배열로 저장한다.
정렬을 수행하는 내부 루프에서 요소들의 접근 비용을 줄이기 위해서이다. 이것은 추가적인 이점이 있다. 정렬에 실패해도 List는 변경되지 않는다.
실패 원자성의 성취나 유지가 가능하다고 해서 항상 바람직한 것은 아니다. 일부 연산의 경우 비용이나 복잡도를 현저하게 증가시킨다.
예외를 묵시하지 말자
try{
...
}catch(SomeException e){
}
catch로 잡아놓고선 아무 처리도 하지 않는다면, 불이 날 것을 대비하지 않는 것과 같은 이치이다. 최소한 catch블록에는 예외를 무시한 이유를 설명하는 주석이라도 한줄 들어가야 한다.
공유하는 가변 데이터에 접근 시 동기화하자
예외를 묵시하지 말자
try{
...
}catch(SomeException e){
}
catch로 잡아놓고선 아무 처리도 하지 않는다면, 불이 날 것을 대비하지 않는 것과 같은 이치이다. 최소한 catch블록에는 예외를 무시한 이유를 설명하는 주석이라도 한줄 들어가야 한다.
'JAVA이야기' 카테고리의 다른 글
'10.03.26 story (0) | 2010.04.01 |
---|---|
'10.03.24 story (0) | 2010.04.01 |
'10.03.22 story (0) | 2010.04.01 |
'10.03.21 story (0) | 2010.04.01 |
'10.03.19 story (0) | 2010.04.01 |