4장은 좀 더 특별하다. 무심코 생성했던 클래스와 인터페이스에 대해 강력한 원칙을 담아 설명한다. 특히나 큰 아키텍처를 설계 및 구현할 때 사용할 수 있는 실용적인 원칙들이 많다.


Item15 – 클래스와 멤버의 접근 권한을 최소화하라.

이유는 너무 다양하다. 컴파일 오류가 생길 수 도 있고 필드가 스레드에 안전하지 않을 수 있다. 같은 의미로 정보 은닉(캡슐화)의 장점으로도 설명할 수 있다. 컴포넌트의 병렬 개발로 시스템 개발 속도를 높이고, 컴포넌트를 교체하는 부담도 적으며, 재 사용성도 있다. 가장 명확한 가이드는 public클래스에 상수 용 public final static 필드 외에는 public 필드를 두지 않는다.


Item16 – 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라(get, set).

Item15의 구현 방법을 이야기한다.


Item17 - 변경 가능성을 최소화하라.

불변 클래스는 안전하며 여러모로 명확하다. 여기서는 불변 클래스를 만드는데 5가지 규칙을 제시한다.

  • 객체의 상태를 변경하는 메서드를 제공하지 않는다.
  • 클래스를 확장할 수 없도록 한다.
  • 모든 필드를 final로 선언
  • 모든 필드를 private으로 선언
  • 자신 외에는 내부의 가변 컴포넌트에 접근 할 수 없도록 한다.


Item18 - 상속보다는 컴포지션을 사용하라.

상속을 많이 써본 사람들의 경험에 의해 나온 내용처럼 느껴진다. 결론은 상속을 하게 되면 뜻하지 않게 문제가 생기는 상황에 대해 이야기한다. 상위 클래스에 새로운 메서드를 추가할 때 생기는 문제, 재정의 했을 때의 오류가 생기거나 성능이 떨어질 수도 있다. 상위 클래스와 하위 클래스가 is-a 관계일 때 (하위는 상위인가?) 상속을 하자.


Item19 - 상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라.

Item18번의 추가되는 설명이다. JAVA8부터는 @impleSpec 태그를 사용하여 내부 구현 방식을 기술할 수 있다. 활성화 명령 매개변수 –tag “ImpleSpec:a:Implementation Requirements:”


Item20 - 추상 클래스보다는 인터페이스를 우선하라.

추상클래스를 사용하였을 때 기능을 추가하는 방법은 상속이다. 템플릿 메서드 패턴을 통해 인터페이스로는 타입을 정의하고 디폴트 메서드를 제공하며 골격 구현 클래스로 나머지 메서드를 구현한다.


Item21 - 인터페이스는 구현하는 쪽을 생각해 설계하라.


Item22 - 인터페이스는 타입을 정의하는 용도로만 사용하라.

상수 인터페이스는 안티패턴이다.


Item24 - 인터페이스는 타입을 정의하는 용도로만 사용하라.


Item25 - 톱 레벨 클래스는 한 파일에 하나만 담으라.

소스 파일들의 컴파일 순서에 따라 동작이 달라지는 걸 막을 수 있다.


출처 : EFFECTIVE JAVA 3/E 조슈아 블로크 지음