Effective Java 3rd ITEM 15

ITEM 15. Minimize the accessibility of classes and members

컴포넌트는 클래스 내부 데이터와 내부 구현 정보를 외부 컴포넌트로부터 잘 숨겨서 설계해야 한다.
오직 API를 통해서만 다른 컴포넌트와 소통하며 서로의 내부 구현에는 전혀 관여하지 않는 이것을 정보 은닉, 캡슐화라고 한다.

정보 은닉의 장점

  1. 여러 컴포넌트를 병렬로 개발할 수 있기 때문에 시스템 개발 속도를 높인다.
  2. 컴포넌트 파악이 쉬워 디버깅하기 좋고, 다른 컴포넌트로 교체하기 쉽기 때문에 관리 비용을 낮춘다.
  3. 최적화할 컴포넌트를 정하고 해당 컴포넌트만 수정하면 되기 때문에 성능 최적화에 도움을 준다.
  4. 독자적으로 사용할 수 있는 컴포넌트라면 다른 환경에서도 유용하게 쓰일 수 있기 때문에 소프트웨어 재사용성을 높인다.
  5. 개별 컴포넌트의 단위 테스트가 가능하여 큰 시스템을 제작하는 난이도를 낮춰준다.
    Java에서의 정보 은닉은 클래스, 인터페이스, 멤버의 접근성을 명시하는 접근 제어 메커니즘이 핵심이다.

모든 클래스와 멤버의 접근성을 가능한 한 좁혀야 한다.

패키지 외부에서 쓸 이유가 없다면 package-private으로 선언하자.

package-private로 선언된 클래스는 내부 구현이 되어 클라이언트를 고려하지 않고 언제든 수정이 가능해진다. 반면에 public으로 선언한다면 하위 호환을 고려해야 한다.

한 클래스에서만 사용하는 package-private 클래스는 private static으로 중첩시켜보자.

private static으로 중첩시켜 넣으면 하나의 클래스에서만 접근할 수 있다.

메서드 재정의

상위 클래스의 메서드를 재정의할 때는 접근 수준을 상위클래스에서보다 더 좁게 설정할 수 없다.

테스트를 위한 접근 범위 수정

private 멤버를 package-private까지 풀어주는 것은 허용 가능하지만 그 이상은 안된다.
테스트 코드를 테스트 대상과 같은 패키지에 두면 package-prviate 요소에 접근할 수 있다.

public 클래스의 필드는 되도록 public이 아니어야 한다.

public으로 선언하면 필드의 값을 제한할 수 없게 된다. 또한 필드가 수정될 때 다른 작업을 할 수 없게 되어 public 가변 필드를 갖는 클래스는 일반적으로 Thread safe 하지 않다.

public static final 필드가 참조하는 객체는 불변이어야 한다.

가변 객체를 참조한다면 final이 아닌 필드에 적용되는 모든 불이익이 그대로 적용된다.

자바 9의 모듈 시스템

기존 4개의 접근 수준과 다르게 모듈에 적용되는 새로운 접근 수준이 있다.
모듈은 자신에 속하는 패키지 중 공개할 패키지를 module-info.java에 선언한다. module-info에 선언되지 않은 클래스는 protected 혹은 public이더라도 모듈 외부에서는 접근할 수 없다.
하지만 꼭 필요한 경우가 아니라면 당분간은 사용하지 않는게 좋을 것 같다.