본문 바로가기
Programming/Java

[이펙티브자바] 아이템15. 클래스와 멤버의 접근 권한을 최소화하라

by 읽고 쓰는 개발자 2023. 3. 12.

아이템15. 클래스와 멤버의 접근 권한을 최소화하라.

 

핵심정리1: 구현과 API를 분리하는 “정보 은닉”의 장점 (모듈화, 캡슐화)

 

l  시스템 개발 속도를 높인다 (여러 컴포넌트를 병렬로 개발할 수 있기 때문)

n  인터페이스 정의서를 바탕으로 서로 다른 모듈을 동시에 개발할 수 있음

l  시스템 관리 비용을 낮춘다 (컴포넌트를 더 빨리 파악할 수 있기 때문)

n  인터페이스 위주로 코드를 살펴보면 코드 파악과 디버깅이 용이함

l  성능 최적화에 도움을 준다 (프로파일링을 통해 최적화할 컴포넌트를 찾고 다른 컴포넌트에 영향을 주지 않고 해당 컴포넌트만 개선할 수 있기 때문)

n  성능의 병목 지점 파악이 용이함 (병목이 일어나는 컴포넌트만 개선하면 됨)

l  소프트웨어 재사용성을 높인다 (독자적인 컴포넌트라면)

l  시스템 개발 난이도를 낮춘다 (전체를 만들기 전에 개별 컴포넌트를 검증할 수 있기 때문)

n  Divide and Quanquer : 나눠서 작은 단위로 개발 가능

 

핵심정리2: 클래스와 인터페이스의 접근 제한자 사용 원칙 세 가지

 

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

l  톱레벨 클래스와 인터페이스에 package-private(default) 또는 public을 쓸 수 있다.

n  톱레벨 클래스는 package-private / public만 가능

n  Public으로 선언하면 API가 되므로 하위 호환성을 유지하려면 영원히 관리
하위호환성 지키지 않은 라이브러리 예) Spring Hateaos  
(API의 발전을 위해 하위호환성이 정답은 아니지만 존중하는게 나음)

n  패키지 외부에서 쓰지 않을 클래스나 인터페이스(내부 구현체)라면 package-private으로 선언

n  인터페이스는 public으로 노출, 구현체는 package-private으로 설정하여 구체적인 구현 로직에 대해 캡슐화 가능

l  한 클래스에서만 사용하는 package-private 클래스나 인터페이스는 해당 클래스에 private static으로 중첩 시키자 (아이템24)

n  Private : 내부에서만 사용하니까 중첩

Static : 왜 private class가 아니라 private static class? (연관관계에 따라 선택)

è Inner private class: 감싸고 있는 외부 인스턴스 항상 참조 (물리적 필드 생김). 감싸고 있는 외부 인스턴스 접근이 언제든 가능

è Inner private static class: 외부 인스턴스 참조하지 않음. 감싸고 있는 인스턴스에 접근 안됨 (독립된 인스턴스)

 

핵심정리3: 멤버(필드, 메서드, 중첩클래스/인터페이스)의 접근 제한자 원칙

 

l  private과 package-private은 내부 구현 -> 은닉해야 하는 정보는 private, package-private

n  public 클래스라도 상수 이외의 인스턴스 필드는 되도록 내부구현으로 정의

l   protected와 public은 공개 API

n  Protected : 상속만 받으면 필드 접근 가능하기 때문에 공개 API

 

완벽 공략

 

l  Serializable : 완벽 공략 13, 객체 직렬화 참고

n  private이더라도, 역직렬화시 모양 그대로 유지해야 하기 때문에 고정된 정보로 의도치 않은 공개 API가 됨

l  리스코프 치환 원칙 : 완벽 공략 26 참고

n  상위 클래스 인스턴스는 하위 클래스 인스턴스로 대체 사용 가능해야한다.

n  상위 – public , 하위 – private 으로 필드, 메소드 선언하면, 상위 클래스 인스턴스를 하위 클래스 인스턴스로 대체했을 때 해당 필드, 메소드 사용 불가

l  스레드 안전 (Thread Safe) : 완벽 공략 38 참고

n  Racing condition : 경합을 바탕으로 순서 및 결과가 보장되지 않는 것. 스레드 안전이 지켜지지 않음

l  불변 객체 : “완벽 공략 24, Value 기반의 클래스” 참고

n  상수로 공개할 필드는 primitive value, 불변 객체를 참고하는 value여야 함

n  가변객체라면, Thread Safe하지 않게 됨

l  자바 9 – 모듈 시스템 (JDK가 모듈 시스템 잘 적용된 가장 대표적인 예시)

n  JSR-376 스팩으로 정의한 자바의 모듈 시스템

n  안정성

-      순환 참조 허용 하지 않음

-      실행시 필요한 모듈 확인

n  Root Path에 module 파일이 있으면 모듈 시스템이 됨 

-      한 패키지는 한 모듈에서만 공개할 수 있음

n  캡슐화 : Public 인터페이스나 클래스라 하더라도 공개된 패키지만 사용할 수 있다. 내부 구현을 보호하는 수단으로 사용 가능 (모듈 아닌 곳에서 참조한다면 의미 없어짐)

n  확장성 : 필요한 자바 플랫폼 모듈만 모아서 최적의 JRE를 구성할 수 있다. 작은 기기에서 구동할 애플리케이션 개발할 때 유용

 

 

출처 : 백기선님 - 이펙티브 자바 완벽 공략 2부