Effective Java | #15. 클래스와 멤버의 접근 권한을 최소화하라

보람·2022년 5월 8일
0

Effective-Java

목록 보기
15/25

잘 설계된 컴포넌트

  • 외부 컴포넌트로부터 얼마나 잘 숨겼느냐, 오직 내부 내용을 완벽히 숨겨, API를 통해서만 외부와 소통하는 것을 정보 은닉, 혹은 캡슐화 라고 한다.
  • 정보 은닉은 시스템 개발 속도를 높이거나 관리 비용을 낮추고 재사용성을 높이는 등의 장점을 보인다.

자바에서는 정보 은닉을 위한 다양한 장치를 제공하는데 그중 하나가 바로

접근 제어 매커니즘

  • 접근 제한자(private, protected, public)로 클래스, 인터페이스, 멤버의 접근성을 명시한다.
  • 기본 원칙 : 모든 클래스와 멤버의 접근성을 가능한 한 좁히기
    • SW가 올바로 동작하는 수준에서 가장 낮은 접근 수준을 부여
  • 접근 수준(낮은 것부터)
    • private : 멤버를 선언한 톱레벨 클래스에서만
    • package-private : 멤버가 소속된 패키지 안의 모든 클래스에서 접근 가능, 접근 제한자 명시 X 적용되는 패키지 접근 수준
    • protected : package-private 의 접근 범위를 포함, 이 멤버를 선언한 클래스의 하위 클래스에서 접근 가능
    • public : 모든 곳

적용

  • 클래스의 공개 API를 세심히 설계 후, 그 외 모든 멤버는 private으로
    • 같은 패키지의 다른 클래스가 접근해야 한다면 (private ->)package-private
    • private & package-private 모두 외부에는 영향 X
    • package-private -> protected : 접근 대상 범위가 엄청나게 넓어짐(주의) => 공개 API이므로 영원히 지원돼야 함😩
    • protected 멤버 수가 적은 것이 좋음
  • 상위 클래스 메서드 재정의시 : 상위 클래스보다 좁게 설정 할 수가 없다 (리스코프 치환 원칙, item-10)
  • public 클래스의 인스턴스 필드는 publicX(item-16)
    • public 가변 필드를 갖는 클래스는 일반적으로 스레드 안전 X
  • 해당 클래스가 표현하는 추상 개념을 완성하는데 꼭 필요한 구성요소로써의 상수라면 public static final 필드로 공개해도 됨
  • 클래스에서 public static final 배열 필드를 두거나 이 필드를 반환하는 접근자 메서드를 제공하면 X
    • 배열은 변경 가능한 값
    • public static final Thing[] VALUES = { ... };
    • 해결책(아래)

public static final 배열 해결책

  1. public 배열을 private으로, public 불변 리스트 추가
private static final Thing[] PRIVATE_VALUES = { ... };
public static final List<Thing> VALUES = Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES));
  1. private 배열, public 복사본 메서드 추가 -> 방어적 복사(item-50)
private static final Thing[] PRIVATE_VALUES = { ... };
public static final Thing[] values() {
	return PRIVATE_VALUES.clone();
}

상황에 따라서 둘 중 하나 선택 가능

모듈시스템

  • 모듈은 패키지들의 묶음
  • 자바9부터 모듈 내부에서 속하는 패키지 중 공개(export)할 것들을 정의 가능 -> 그 외에 것들은 외부에 영향X

핵심 정리

프로그램 요소의 접근성은 가능한 한 최소한으로 하라. 꼭 필요한 것만 골라 최소한의 public API를 설계하자. 그 외에는 클래스, 인터페이스, 멤버가 의도치 않게 API로 공개되는 일이 없도록 해야 한다. public 클래스는 상수용 public static final 필드 외에는 어떠한 public 필드도 가져서는 안 된다. pubilc static final 필드가 참조하는 객체가 불변인지 확인하라.

profile
백엔드 개발자

0개의 댓글