잘 설계된 모듈과 그렇지 못한 모듈을 구별 짓는 가장 중요한 속성 하나는 모듈 내부의 데이터를 비록한 구현 세부사항을 다른 모듈에 잘 감추냐의 여부다
잘 설계된 모듈은 구현 세부사항을 전부 API 뒤쪽에 감춘다. 모듈들은 이 API를 통해서만 서로 통신하며, 각자 내부적으로 무슨 짓을 하는지는 신경 쓰지 않는다.
이 개념은 정보 은닉(information hiding) 또는 캡슐화(encapsulation) 이다.
정보 은닉은 시스템을 구성하는 모듈 사이의 의존성르 낮춰서, 각자 개별적으로 개발하고, 시험하고, 최적화 하고, 이해하고, 변경할 수 있도록 한다.
정보 은닉은 모듈간의 의존성이 낮으므로 각 모듈은 다른 소프트웨어 개발에도 유용하게 쓰일 수 있다.
원칙은 단순하다. 각 클래스와 멤버는 가능한 한 접근 불가능하도록 만들라는 것
최상위 레벨 클래스와 인터페이스는 가능한 package-private로 선언해야 한다.
package-private로 선언하면 API의 일부가 아니라 구현 세부사항에 속하게 되므로, 다음번 릴리스에 클라이언트 코드를 깨뜨릴 걱정 없이 자유로이 변경하거나 삭제하거나, 대체할 수 있게 된다.
=> package 밖으로 나갈 수 없으므로 클라이언트가 Class를 불러서 사용할 수 없다. 그러므로 자유로이 변경할 수 있게 된다.
반대로 public으로 선언하게 되면 호환성을 보장하기 위해 해당 객체를 계속 지원해야 한다.
접근자들
private - 해당 접근자로 선언된 멤버는 선언된 최상위 레벨 클래스 내부에서만 접근 가능하다.
package-private - 해당 접근자로 선언된 멤버는 같은 패키지 내의 아무 클래스나 사용할 수 있다.
protected - 이렇게 선언된 멤버는 선언된 클래스 및 그 하위 클래스만 사용할 수 있다. 선언된 클래스와 같은 패키지에 있는 클래스에서도 사용이 가능하다.
public - 이렇게 선언된 멤버는 어디서도 사용이 가능하다.
객체 필드(instance field)는 절대로 public으로 선언하면 안 된다.
변경 가능 public 필드를 가진 클래스는 다중 스레드에 안전하지 않다.
public static final 배열 필드를 두거나, 배열 필드를 반환하는 접근자(accessor)를 정의하면 안되다.
=> 클라이언트가 배열 내용을 변경할 수 있게 되므로 보안에 문제가 생긴다.