티스토리 뷰
잘 설계된 컴포넌트는 외부로부터 내부 구현이 잘 숨겨져 있어서 구현과 API가 깔끔히 분리되어 있다.
이것을 정보은닉, 또는 캡슐화라고 한다.
정보 은닉의 장점
- 시스템 개발 속도 향상
- 시스템 관리 비용 절감
- 성능 최적화에 도움을 줌
- 소프트웨어 재사용성 향상
- 큰 시스템 제작의 난이도 감소
접근 제한 수준
- private : 멤버를 선언한 톱레벨 클래스만 접근 가능
- package-private(default) : 멤버가 소속된 패키지 안의 모든 클래스에서 접근 가능
- protected : package-private의 접근 범위 포함, 이 멤버를 선언한 클래스의 하위 클래스에서도 접근 가능
- public : 모든 곳에서 접근 가능
접근 제한자 활용 원칙
모든 클래스와 멤버의 접근성을 가능한 한 좁힌다.
- public 클래스의 인스턴스 필드는 되도록 public이 아니어야 한다
- final이 아닌 필드를 public 으로 선언할 경우에는, 해당 필드에 담는 값을 제한할 수 없게 되기 때문
- 필드가 수정될 때 다른 작업을 할 수 없게 되어서 스레드 안전하지 않기 때문
- 해당 클래스의 추상 개념을 완성하는 데 꼭 필요한 상수라면 public static final로 공개할 수 있음
- 클래스에서 public static final 배열 필드를 두거나 이 필드를 반환하는 접근자 메서드를 제공해서는 안된다
- 길이가 0이 아닌 배열은 변경이 가능하기 때문
잘못된 예
public static final Thing[] VALUES = { ... };
올바른 예
// 1 : 배열을 private으로 만들고 public 불변 리스트를 추가하는 방식
private static final Thing[] PRIVATE_VALUES = { ... };
public static final List<Thing> VALUES =
Collections.unmodifiableList(Arrays.asList(PRIVAZTE_VALUES));
// 2 : 배열을 private으로 만들고 복사본을 반환하는 방식
private static final Thing[] PRIVATE_VALUES = { ... };
public static final Thing[] values() {
return PRIVATE_VALUES.clone();
}
핵심 정리
- 프로그램 요소의 접근성은 가능한 한 최소한으로
- public 클래스는 상수용 public static final 필드 외에는 어떠한 public 필드도 가져선 안됨
- public static final 필드가 참조하는 객체가 불변인지 확인하라
자바 9에 추가된 모듈 시스템
자바 9로 넘어가면서 모듈 시스템이라는 개념이 추가되었는데, 이 모듈 시스템을 통해 새로운 수준의 가시성 제어가 가능해졌다. 기존의 접근 제어자는 패키지나 클래스 수준의 가시성 제어를 위한 기능이었다. 모듈 시스템을 통해 모듈 수준의 가시성 제어가 가능해진 것이다.
스터디에서 이 부분에 대한 질문이 들어왔는데, 책에서 말하는 두가지 암묵적 접근 수준은 구체적으로 뭘 말하는 것일까?
두가지 암묵적 접근 수준?
접근 수준에 대해서 다소 잘못된 부분이 있어 정정하면,
- 모듈 내부 접근 수준 - 모듈 내에서는 암묵적으로 모든 요소에 접근 가능, 모듈의 멤버(패키지)를 공개하지 않으면 해당 패키지 내부의 클래스들이 공개(public, protected)되어 있더라도 외부 모듈에서는 접근이 불가능
- 모듈 간(외부) 접근 수준 - 명시적으로 export 문을 사용해 공개된 패키지만 다른 모듈에서 접근 가능, 모듈을 클래스패스에 두면 모듈의 패키지 공개여부와 상관없이 공개(public, protected)된 클래스에는 외부 모듈에서 접근 가능
아래 글들을 참고했다.
- https://www.digitalocean.com/community/tutorials/java-9-modules
- https://scshim.tistory.com/371
- https://iyoungman.github.io/java/Java9-Module/
package-private 를 적절하게 사용하는 방법?
공유받은 글에 따르면 package-private 이 실무에서 잘 쓰이지도 않고, 적절하게 활용할 수 있는 상황이 잘 나오지 않는 것 같다.
관련해서 괜찮은 글을 찾아 답변드렸다. 해당 글에서는 크게 7가지 사항을 얘기한다.
- package-private 클래스는 다른 패키지에 표시되지 않으므로 자주 사용하면 안된다.
- package-private 클래스를 사용하는 경우 패키지에서만 클래스에 액세스할 수 있는지 확인해라.
- package-private 클래스에서 public 메소드를 만드는 것을 피하라.
- package-private 클래스의 모든 데이터가 적절한 접근 제어자로 보호되는지 확인하라.
- 가능한 한 package-private 클래스 대신 인터페이스를 사용하라.
- 모든 package-private 클래스에 적절한 Javadoc 주석이 있는지 확인하라.
- 보안을 위해 package-private 클래스에 의존하지 마라.
위 7가지 사항들을 전부 고려하며 package-private 제어자를 사용하는 것은 쉽지 않을 것 같다. 실무에서 잘 쓰이지 않는 것도 이러한 이유 때문이 아닐까
'스터디 > 이펙티브자바' 카테고리의 다른 글
인터페이스는 구현하는 쪽을 생각해 설계하라 (0) | 2023.01.31 |
---|---|
생성자에 매개변수가 많을 때는 빌더를 고려하라 (0) | 2022.12.22 |
Optional을 사용하는 이유 (2) | 2022.12.08 |
댓글