개발 공부 기록하기/01. JAVA & Kotlin

짧은 코멘트와 함께하는 이펙티브 자바) #19 상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라

lannstark 2020. 10. 19. 21:48

짧은코멘트

  1. Spring 애플리케이션 개발자가 상속을 할 일은 생각보다 많지 않다. 중복되는 필드가 있는 경우 데이터 구조를 표현하기 위한 정도...?
  2. 요즘에는 IDE가 원낙 잘 되어 있어 프로젝트에서 사용하는 모든 클래스에 final을 붙일 필요까지는 없는 것 같다. 같은 팀끼리는 의사소통이 잘 되는 측면도 있고... 몇몇 유틸성 클래스에 private constructor를 잘 달아주는 정도면 충분할 것 같다.

 

상속을 고려한 설계와 문서화

상속용 클래스를 설계하기란 결코 만만치 않다. 상속용 클래스를 만들려면

  1. 클래스 내부에서 스스로를 어떻게 사용하는지 (자기 사용 패턴) 모두 문서로 남겨야 한다. 이때 @implSpec 태그를 사용할 수 있다.
  2. 상속과 관련되어 문서화한 것은 그 클래스가 사용되는한 반드시 지켜야 한다. 그렇지 않으면 그 내부 구현 방식을 믿고 활용하던 하위 클래스를 오작동하게 만들 수 있다.
  3. 다른 사람들이 효율적인 하위 클래스를 만들 수 있도록 클래스의 내부 동작 과정 중간에 끼어들 수 있는 훅(hook)을 잘 선별하여 protected 메소드 형태로 공개해야 할 수 있다.
  4. 상속용 클래스의 생성자는 직접적으로든 간접적으로든 재정의 가능 메소드를 호출해서는 안 된다. 
  5. Cloneable과 Serializable 인터페이스 둘 중 하나라도 구현한 클래스를 상속할 수 있게 설계하는 것은 일반적으로 좋지 않은 생각이다. 만약 두 인터페이스를 구현한 클래스를 상속하게 하려면 clone과 readObject 모두 직접적으로든 간접적으로든 재정의 가능 메소드를 호출해서는 안된다.

 

상속용으로 설계하지 않은 클래스는 상속을 금지해야 한다. 이때 사용할 수 있는 방법은 두 가지 이다.

  1. 클래스를 final로 선언
  2. 모든 생성자를 private이나 default로 선언하고 public 정적 팩토리를 제공