제육's 휘발성 코딩
article thumbnail
반응형

클래스와 멤버의 접근 권한을 최소화하라

잘 설계된 컴포넌트는 내부 데이터와 내부 구현 정보를 외부 컴포넌트로부터 잘 숨긴 컴포넌트이다. 모든 내부 구현을 완벽히 숨기고, 구현과 API를 깔끔히 분리하는 것이 중요하다. 이를 정보 은닉 혹은 캡슐화라고 한다.

 

정보 은닉의 장점

  • 여러 컴포넌트를 병렬로 개발할 수 있기 때문에 시스템 개발 속도를 높인다.
  • 디버깅과 교체에 용이하여 시스템 관리 비용을 낮춘다.
  • 다른 컴포넌트에 영향을 주지 않기 때문에 제작 난이도를 낮추고 성능 최적화와 SW 재사용에 도움을 준다.

 

접근 제어자

자바에서는 정보 은닉을 위해 접근을 제어하는 메커니즘을 제공한다.

  • public : 모든 곳에 접근할 수 있다. (공개 API - 영원한 관리 필요)
  • protected : package-private의 범위를 포함하며, 이 멤버를 선언한 클래스의 하위 클래스에서도 접근이 가능하다.
  • package-private : default 접근 제어자며, 같은 패키지 안에서만 접근할 수 있다. 단, 인터페이스의 멤버는 기본적으로 public이 적용된다.
  • private : 멤버를 선언한 현재 클래스에서만 접근할 수 있다.

 

컴포넌트 설계

컴포넌트를 설계할 때는 public(공개 API)을 세심히 설계한 후, 그 외의 모든 멤버는 private으로 만드는 것이다. 즉, 꼭 필요한 API가 아니라면 접근성을 최대한 좁혀서 가장 낮은 접근 지정자 수준을 부여해야 한다.

 

public 클래스의 관점에서 멤버의 접근 수준을 package-private에서 protected로 바꾸는 순간 그 멤버에 접근할 수 있는 대상 범위가 넓어진다. 즉, protected 멤버는 공개 API(동일 패키지)가 되므로 영원히 지원돼야 한다. 따라서 protected 멤버의 수는 적을수록 좋다.

 

멤버의 접근성을 좁히면서 주의할 점은 상위 클래스의 메서드를 재정의할 때는 그 접근 수준을 상위 클래스에서보다 좁게 설정할 수 없다는 것이다. 해당 규칙을 어길 경우 컴파일 오류가 발생한다. SOLID 5원칙의 L(리스코프 치환 원칙 - 상위 클래스는 하위 클래스의 인스턴스로 대체할 수 있어야한다.)이 해당 의미이다.

public 클래스 주의점

public 클래스의 인스턴스 필드들은 되도록 public이 아니어야 한다. 필드가 가변 객체를 참조하거나, final이 아닌 인스턴스 필드를 public으로 선언하면 외부에서 접근이 가능하므로 그 필드에 담을 수 있는 값을 제한할 힘을 잃게 된다. 또한, 자연스럽게 스레드 세이프하지 않게 된다.

 

예외적으로 public static final 필드를 통해 상수를 표현하는 경우는 대문자 네이밍의 관례를 기반으로 public 메서드로 사용한다. (단, 추상 개념을 완성하는 데 꼭 필요한 구성 요소의 상수인 경우)

 

// 방법 1 : 문제 발생 가능성 존재
public static final Thing[] VALUES = {...};

// 방법 2 : private 배열로 생성 후 , public 불변 리스트 추가
private static final Thing[] PRIVATE_VALUES = {...};
public static final List<Thing> VALUES = Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES));

// 방법 3 : private 배열로 생성 후, 복사본을 반환
private static final Thing[] PRIVATE_VALUES = {...};
public static final Thing[] values() {
  return PRIVATE_VALUES.clone(); 
}
  • 클라이언트가 무엇을 원하는 지 여부에 따라 방법 2 나 3 중에 선택하여 사용하자.

 

정리

자바 9 버전부터는 모듈 시스템을 통해 패키지를 묶을 수 있는 기능도 있다. JDK 외에도 모듈 개념이 널리 받아들여질지 예측하기는 쉽지 않을 것이다. (자바 8 버전 쓰는 회사도 많기 때문)

 

프로그램을 설계할 때 최소한의 public API를 설계하고, 그 외에 의도치 않게 공개되는 일이 없도록 하자.

public 클래스는 public static final 필드를 제외한 어떠한 필드도 public 필드를 갖지 않도록 하자. 또한 public static final 필드가 참조하는 객체가 불변인지 확인하자.

반응형
profile

제육's 휘발성 코딩

@sasca37

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요! 맞구독은 언제나 환영입니다^^