[Elegant-object] 5. retire

다룰 내용

4.1 절대 NULL을 반환하지 마세요  
4.2 체크 예외(checked exception)만 던지세요   
4.3 final이거나 abstract이거나   
4.4 RAII를 사용하세요

1 4.1 절대 NULL을 반환하지 마세요 이 글에서는 Null을 사용하지 말라는 이유로 또 다시 객체지향을 언급합니다.

public String title(){
  if(/* title이 없다면 */){
    return null;
  }
  return "Elegant Objects"
}

앞에 내용 중에 Null에 대한 언급이 있었는데, 인자로 Null을 넣지 말아야한다는 말이 있습니다. 이 절에는 null인자로 받았을 경우라서 조금 다릅니다.

위 함수를 실행합니다. String title = x.title(); print(title.length()); 의 경우 NullPointException이 일어날 수 있다는 잠재적인 장애를 가진 객체가 되어버립니다. 저자는 이를 객체에 대한 신뢰(trust) 가 무너졌다고 말합니다.

객체가 더이상 자립적이지 못하고, 견고하지 못하고, 객체에게 작업을 요청한 후 안심하고 결과에 의지할 수 없습니다.

그러면서 저자는 객체라는 존재에 대한 자신의 생각을 말합니다.

객체라는 사상에는 우리가 신뢰하는 엔티티라는 개념이 담겨져 있습니다. 객체는 우리의 의도에 관해 전혀 알지 못하는 데이터 조각이 아닙니다. 쉽게 접근할 수 있는 메모리 공간과 유용한 서브루틴만을 제공하는 단순한 데이터 조각이 아니고, 한 위치에서 다른 위초 보내는 표식도 아니고, 데이터를 담는 봉투도 절대 아닙니다.

그렇다면 왜 Java는 NULL이라는 것을 반환하게 했을까? 저자는 JDK를 설계하는 사람들이 빠르게 실패하기 보다는 안전하게 실패하기 에 좀 더 중심을 두었을 것이라고 말합니다.

빠르게 실패하기 vs 안전하게 실패하기

아래는 저자가 말한 부분입니다.

안전하게 실패하기는 버그, 입출력 문제, 메모리 오버플로우 등이 발생한 상황에서도 소프트웨어가 계속 실행될 수 있도록 최대한 많은 노력을 기울일 것을 권장합니다. 어떤 상황이 닥치더라도 소프트웨어는 생존하기 위해 노력해야 합니다. NULl을 반환하는 방법도 일종의 생존 기법입니다. 디렉토리에 포함된 모든 파일을 나열하는 요청에서 비어있다면 이작업은 처리하기 불가능합니다. 이것은 전적으로 요청자의 잘못이지만, 안전하기 실패하기에서는 이 상황을 구조하기 위해 노력합니다. 아무도 반환한 배열을 사용하지 않아서 NullPointerException이 발생하지 않을 것이라는 희망을 품은 책 말이죠

반대로 빠르게 실패하기는 정반대의 접근 방식을 따릅니다. 일단 문제가 발생하면 곧바로 실행을 중단하고 최대한 빨리 예외를 던집니다. 결과에 대해서는 걱정하지 않습니다. 만약 소프트웨어가 부서지기 쉽고 모든 단일 제어 지점(single control point)에서 중단되도록 설계됐다면, 단위 테스트에서 실패 상황을 손쉽게 재현할 수 있을 것입니다. 따라서 문제를 간단하게 수정할 수 있습니다. 상황을 구조하지 않는 대신, 가능하면 실패를 분명하게(flagrant)만듭니다.

그럼 Null을 어떻게 처리하지?

public User user(String name){
  if (/* 데이터베이스에서 발견하지 못했다면 */){
    return null;
  }
  return /* 데이터베이스로부터 */
}

위 코드에서 Null을 처리하기 위해서는 2개의 함수로 나눠서 해결한다. 또는 널 오브젝트 패턴을 사용해서 해결한다.

저자는 절대로 NULL을 반환하지 말라고 한다. 생각도 하지 말라고 한다.

4.2 체크 예외(checked exception)만 던지세요 이 내용은 나도 어느정도 공감하는 부분에 내용인데, 해당 내용을 블로그로 다뤄본적이 있다. 여기!

4.3 final이거나 abstract이거나 이 절에는 조금 흥미로웠던 것은 저자의 생각이였단 우리는 일반적으로 클래스라는 것을 만든다. 예를 들면 class Int{} 이런 식으로? 저자는 이런 Default 클래스를 하지 말아야 한다고 말하고 있습니다. 일반 클래스에 상속을 사용하게 될 경우, 계층 구조를 어렵게 만들기도 하고, 최고의 문제점은 가상메서드(virtual method) 이라고 합니다.

이 부분도 예전에 고민해봤던 내용인데, 해당 내용을 어디에 적었었는데, 기억이 안나네요.

요는 클래스가 가질수 있는 것은 오직 final이거나 abstract 이여야 한다고 말하고 있습니다.

4.4 RAII를 사용하세요 는 자바에서 try-with-resources 기법을 사용해라 라는 의미입니다.