본문 바로가기
Java

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

by jayden-lee 2019. 4. 11.
728x90

Effective Java 3판을 학습하며 요약한 내용입니다. 자세한 내용은 책을 참고해주시기 바랍니다.

컴포넌트 설계 시 중요한 점은 클래스 내부 데이터와 내부 구현 정보를 외부 컴포넌트로부터 잘 숨겼는지(은닉화)가 중요하다. 잘 설계된 컴포넌트는 내부에 사용되는 것과 API로 공개하는 것을 깔끔하게 분리한다. API를 통해서만 다른 컴포넌트와 소통하며, 서로의 내부 동작 방식에는 관심이 없다.

정보 은닉 장점

  1. 시스템 개발 속도를 높인다.
  2. 시스템 관리 비용을 낮춘다.
  3. 성능 최적화에 도움을 준다.
  4. 소프트웨어 재사용을 높인다.
  5. 큰 시스템을 제작하는 난이도를 낮춘다.

접근 제어 매커니즘은 클래스, 인터페이스, 멤버의 접근성(접근 허용 범위)를 명시한다. 각 요소의 접근성은 요소가 선언된 위치, 접근 제한자로 정해진다. 접근 제한자를 제대로 활용하는 것이 자바에서 정보 은닉의 핵심이다.

 

모든 클래스와 멤버의 접근성을 최대한 좁혀야 한다. 동작할 수 있는 범위 내에서 가장 낮은 접근 수준을 부여하는 것이 좋다.

자바 접근 제한자

접근 제어자 설명
public 어떤 클래스라도 접근이 가능하다.
protected 동일 패키지 내에 있는 클래스와 하위 클래스에서만 가능하다
default (package private) 동일 패키지에서만 접근이 가능하다. 접근제어자를 별도로 설정하지 않는다면 default가 접근 제어자가 된다.
private 클래스 내에서만 접근이 가능하다.

자바 배열은 변경 가능하니 접근자 주의

클래스에 public static final 배열 필드를 두거나 해당 배열을 반환하는 접근자 메서드를 제공하면 안된다. 클라이언트는 접근자메서드를 통해 배열을 접근하고 내용을 수정할 수 있기 때문이다.

public static final Thing[] VALUES = { ... };

이를 해결하는 방법은 두 가지다.

 

첫 번째 방법은 public을 private으로 변경하고, public 불변 리스트를 추가하는 것이다.

private static final Thing[] PRIVATE_VALUES = { ... };
public static final List<Thing> VALUES = Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES));

두 번째 방법은 배열을 private으로 만들고, 원본이 아닌 복사본을 반환하는 public 메서드를 추가하는 것이다.

private static final Thing[] PRIVATE_VALUES = { ... };
public static final Thing[] values() {
	return PRIVATE_VALUES.clone();
}

자바 9 모듈 시스템

자바 9부터는 모듈 시스템이 도입되면서 두 가지 암묵적 접근 수준이 추가되었다. 패키지가 클래스들의 묶음인 것처럼 모듈은 패키지들의 묶음이다.

 

  1. 모듈은 패키지 중 공개할 것들을 선택해서 외부로 공개할 수 있다. public 또는 protected 접근 제한자라도 모듈에서 해당 패키지를 공개하지 않으면, 모듈 외부에서는 접근이 불가능하다.
  2. 모듈의 JAR 파일을 자신의 모듈 경로가 아닌 애플리케이션의 클래스패스에 두면, 모듈 안의 모든 패키지는 모듈이 없는 것처럼 동작한다. 즉, 모듈에서 공개 했는지 여부와 상관없이 외부에서 public 또는 protected 멤버를 모듈 밖에서도 접근할 수 있게 된다.

요약

프로그램의 요소들의 접근성은 가능한 최소화해야 한다. 접근성 범위가 가장 큰 public 접근 제한자는 정말 필요한 API에서만 사용하도록 설계해야 한다. 클래스 또는 인터페이스 내에서 필드는 public 접근 제한자를 최대한 갖지 말아야한다. 단, 중첩 클래스에서 사용하거나 또는 상수를 나타날 때 사용하는 경우는 예외이다.

댓글