<aside>
<img src="/icons/help-alternate_gray.svg" alt="/icons/help-alternate_gray.svg" width="40px" />
들어가기에 앞서
추상화의 기본 단위인 클래스와 인터페이스는 자바 언어의 심장과도 같다. 그래서 자바 언어에는 클래스와 인터페이스 설계에 사용하는 강력한 요소가 많다. 이런 요소를 적절히 활용하여 편하고, 견고하며, 유연하게 만드는 방법을 알아보자!
</aside>
15] 클래스와 멤버의 접근 권한을 최소화하라
Q. 어설프게 설계된 컴포넌트와 잘 설계된 컴포넌트의 가장 큰 차이는 무엇일까?
A. 클래스 내부 데이터와 내부 구현 정보를 외부 컴포넌트로부터 얼마나 잘 숨겼느냐이다. 잘 설계된 컴포넌트는 모든 내부 구현을 완벽히 숨겨서 구현과 API를 깔끔하게 분리한다. 오직 API를 통해서만 다른 컴포넌트와 소통하며 서로의 내부 동작 방식에는 전혀 개의치 않는다. **정보 은닉(캡슐화)**라고 하는 개념은 소프트웨어 설계의 근간이 되는 원리다.
그렇다면 정보 은닉(캡슐화)을 하면 뭐가 좋은가?
- 개발 속도를 높일 수 있다.(컴포넌트를 병렬로 개발)
- 시스템 관리 비용을 낮출 수 있다.(컴포넌트를 더 빨리 파악하여 디버깅, 교체에 용이)
- 성능 최적화에 도움이 된다.(완성된 시스템을 프로파일링 후 컴포넌트만 최적화 가능)
- 스포트웨어 재사용성을 높인다.(단 컴포넌트 독자적으로 동작할 수 있어야 함)
- 큰 시스템을 제작하는 난이도를 낮춰준다.(개별 컴포넌트의 동작을 검증해가며 개발)
자바의 정보 은닉의 핵심: 접근 제한자
자바에서 제공해주는 다양한 장치(접근 제어 케머니즘) 중 하나로 각 요소의 접근성을 그 요소가 선언된 위치와 접근 제한자로 정할 수 있다. 이 접근 제한자를 잘 활용하는 것이 핵심이다.
기본 원칙: 모든 클래스와 멤버의 접근성을 가능한 한 좁혀야 한다.
- 톱레벨 클래스와 인터페이스를 선언할 때 package-private으로 선언하자.
공개 API를 만드는 것이 아니라면, package-private으로 선언하자. 그렇다면 클라이언트에 아무런 피해 없이 다음 릴리스에서 수정, 교체, 제거할 수 있다. 반면 public으로 선언한다면 API가 되므로 하위 호환을 위해 계속 관리해줘야만 한다.
- 한 클래스에서만 사용하는 package-private 톱레벨 클래스나 인터페이스는 이를 사용하는 클래스 안에 private static으로 중첩시켜보자.
- 우선 public일 필요가 없는 클래스의 접근 수준을 package-private 톱레벨 클래스로 좁혀보자.(
public(API)
→package-private(내부 구현)
)
- 한 클래스에서만 사용하고 있는 package-private 톱레벨 클래스나 인터페이스를 클래스 안에 private static으로 중첩시켜보자.(
package-private
→ private static
)
package-private일 때는 같은 패키지의 모든 클래스가 접근 할 수 있지만 중첩시키면 바깥 클래스 하나에서만 접근할 수 있다.
- 클래스의 공개 API를 설계한 후, 그 외의 모든 멤버는 private로 만들자
그다음 오직 같은 패키지의 다른 클래스가 접근해야 하는 멤버에 한하여 package-private로 바꿔주자.
만일 권한을 푸는 일이 자주 발생하게 되면 시스템에서 컴포넌트를 더 분해해야 하는 것은 아닌지 고민해 보자.