일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Spring
- Storm
- Clean Code
- hdfs
- DDD
- Angular2
- hibernate
- 엘라스틱서치
- Java
- Domain Driven Design
- apache storm
- elasticsearch
- intellij
- scala
- Spring Batch
- Gradle
- SBT
- design pattern
- docker
- 제주
- Hbase
- Spring Boot
- nginx
- spark
- Spring XD
- Linux
- hadoop
- 스프링 배치
- elastic search
- 도메인주도설계
- Today
- Total
욱'S 노트
Clean Code - 오류처리 본문
오류 코드보다 예외를 사용하라
얼마 전까지만 해도 예외를 지원하지 않는 프로그래밍 언어가 많았다. 예외를 지원하지 않는 언어는 오류를 처리하고 보고하는 방법이 제한적이었다. 당시의 방법에서는 호출자의 코드가 복잡해진다. 함수를 호출한 즉시 오류를 확인해야 하기 때문이다. 불행히도 이 단계는 잊어버리기 쉽다.
Try-Catch-Finally 문부터 작성하라
try 블록에서 무슨일이 생기든지 catch 블록은 프로그램 상태를 일관성 있게 유지해야 한다. 그러므로 예외가 발생할 코드를 짤때는 try-catch-finally 문부터 시작하는 편이 낫다
Unchecked 예외를 사용하라
확인된 예외가 반드시 필요하지 않다는 사실이 분명해졌다. 다양한 언어(C#, C++, 파이썬, 루비)에서 checked exception을 지원하지 않는데 안정적인 소프트웨어를 구현하는데 무리가 없다.
확인된 예외는 OCP를 위반한다. 메서드에서 확인된 예외를 던졌는데 catch 블록이 세단계 위에 있다면 그 사이 메서드 모두가 선언부에 해당 예외를 정의해야 한다. 즉, 하위 단계에서 코드를 변경하면 상위 단계 메서드 선언부를 전부 고쳐야 한다는 말이다.
throws 경로에 위치한 모든 함수가 최하위 함수에서 던지는 예외를 알아야 하므로 캡슐화도 깨진다. 오류를 원거리에서 처리하기 위해 예외를 사용한다는 사실을 감안한다면 이처럼 확인된 예외가 캡슐화를 깨버리는 현상은 참으로 유감스럽다.
예외에 의미를 제공하라.
예외를 던질 때는 전후 상황을 충분히 덧붙인다. 오류 메시지에 정보를 담아 예외와 함께 던진다. 실패한 연산 이름과 유형도 언급한다.
호출자를 고려해 예외 클래스를 정의하라.
어플리케이션에서 오류를 정의할 때 프로그래머에게 가장 중요한 관심사는 오류를 잡아내는 방법이 되어야 한다.
ACMEPort port = new ACMEPort(12);
try {
port.open();
} catch (DeviceResponseException e) {
reportPortError(e);
logger.log("Device response exception", e);
} catch (ATM1212UnlockedException e) {
reportPortError(e);
logger.log("Unlock exception", e);
} catch (GMXError e) {
reportPortError(e);
logger.log("Device response exception");
} finally {
...
}
위의 코드는 다음과 같이 간결해 질 수 있다.
LocalPort port = new LocalPort(12);
try {
port.open();
} catch (PortDeviceFailure e) {
reportError(e);
logger.log(e.getMessage(), e);
} finally {
...
}
public class LocalPort {
private ACMEPort innerPort;
public LocalPort(int portNumber) {
innerPort = new ACMEPort(portNumber);
}
public void open() {
try {
innerPort.open();
} catch (DeviceResponseException e) {
throw new PortDeviceFailure(e);
} catch (ATM1212UnlockedException e) {
throw new PortDeviceFailure(e);
} catch (GMXError e) {
throw new PortDeviceFailure(e);
}
}
...
}
'Methdology > Clean Code' 카테고리의 다른 글
Clean Code - 경계 (0) | 2015.07.20 |
---|---|
Clean Code - 객체와 자료구조 (0) | 2015.07.15 |
Clean Code - 형식 맞추기 (0) | 2015.07.10 |
Clean Code - 주석 (0) | 2015.07.08 |
Clean Code - 함수 (0) | 2015.07.03 |