The rule of thumb is simple: make each class or member as inaccessible as
possible
객체지향의 핵심
잘 설계된 시스템의 핵심은 정보 은닉, 그리고 캡슐화다. 내부 구현과 API를 깔끔히 분리한 컴포넌트는 다른 컴포넌트와 쉽게 분리할 수 있다. 이렇게 독립한다면, 개발/테스트/최적화/적용/분석/수정을 개별적으로 할 수 있어 유연한 시스템이 된다.
캡슐화의 장점
1.
시스템 개발 속도를 높인다. 컴포넌트를 병렬적으로 개발할 수 있으니까.
2.
시스템 관리 비용을 낮춘다. 공개 API만 확인함으로써 객체의 역할을 쉽게 파악할 수 있고, 다른 컴포넌트로 교체하기도 쉽다
3.
성능 최적화에 도움을 준다. 완성된 시스템을 프로파일링해 최적화할 컴포넌트를 정하고, 다른 컴포넌트에 영향을 주지 않으면서 해당 컴포넌트만 최적화 할 수 있다.
4.
코드 재사용성을 높인다. 외부에 거의 의존하지 않고 독자적으로 동작할 수 있는 컴포넌트는 다른 환경에서도 유용하게 쓰일 가능성이 크다.
5.
큰 시스템을 제작하는 난이도를 낮춰준다. 시스템 전체가 아직 완성되지 않은 상태에서도 개별 컴포넌트의 동작을 검증할 수 있기 때문이다.
자바가 제공하는 정보 은닉
자바의 접근제어자는 캡슐화의 핵심이다. 기본 원칙은 가능한한 클래스와 멤버의 접근성을 좁혀야 한다는 것이다. 소프트웨어가 동작하는 한 가장 낮은 접근수준을 유지하라.
public으로 선언한 API는 이후 릴리스에서 하위 호환을 위해 영원히 관리해야 한다.
package-private 클래스
멤버나 메서드 뿐만 아니라 클래스 또한 어디까지 공개할지 결정해야 하는데, pulbic 클래스는 패키즈의 api임을 기억하라. 그럴 이유가 없는 클래스는 package-private 클래스로 만들어서 관리해야 한다.
접근제어자 부여시 팁 & 주의할 점
1.
클래스의 공개 API를 세심히 설계한 후 모든 멤버를 private로 만든다. 이후 같은 패키즈의 다른 클래스가 접근해야 하는 멤버는 package-private로 풀어준다.
만약 권한을 풀어주는 일이 자주 일어난다면 설계를 고민해보자!
2.
Serializable을 구현한 클래스는 필드들이 public이 아니더라도 의도치 않게 공개 API가 될 수 있으므로 주의하자
3.
public 클래스의 멤버 접근 수준이 protected 이상이라면 멤버에 접근할 수 있는 대상 범위가 매우 늘어난다. 공개 API로 간주하고 영원히 지원되야 함을 명심하자.
4.
테스트를 위해 접근제어자를 풀어주는 건 어느정도 허용되지만, public으로 만드는 것은 안 된다.
5.
public 클래스의 인스턴스 필드는 public이어선 안된다. 해당 필드를 누구나 수정할 수 있음으로 인해, 그 필드와 관련된 모든 불변식을 보장할 수 없게 된다. 또한 스레드 안전하지 않다. 거기에 더해 해당 필드를 수정하는 동안엔 스레드 락이 걸려서 다른 스레드는 해당 객체를 수정할 수 없을 것이다.
위에 대한 예외로, 해당 클래스의 개념을 구현하는 데 꼭 필요한 상수라면 public으로 둘 수 있다. 상수는 final 해야하며 불변이어야 한다. 길이가 0이 아닌 배열은 모두 변경 가능하니 상수가 아니다.
용어정리
한글명 | 영어명 |
잊기 쉬운 | oblivious |
경험 법칙 | rule of thumb |
이후에 | subsequent |
의무가 있는 | obligated |
무상으로 | gratuitously |