아이템15. 클래스와 멤버의 접근 권한을 최소화하라
잘 설계된 컴포넌트의 가장 큰 핵심은 클래스 내부 데이터와 내부 구현정보를 외부 컴포넌트로부처 얼마나 잘 숨겼느냐 다. 모든 내부 구현을 완벽히 숨겨, 구현과 API를 분리하고 오직 API를 통해서만 다른 컴포넌트와 소통하며 서로의 내부 동작에는 전혀 개의치 않는다. 정보은닉, 혹은 캡슐화라고 한다.
캡슐화) 의 장점
정보은닉 (=- 시스템 개발 속도를 높인다.
- 시스템 관리 비용을 낮춘다.
- 정보 은닉 자체가 성능을 높여주진 않지만, 성능 최적화에 도움을 준다. 완성된 시스템을 프로파일링해 최적화할 컴포넌트를 정한 다음, 다른 컴포넌트에 영향을 주지 않고 해당 컴포넌트만 최저화할 수 있기 때문이다.
- 소프트웨어 재사용성을 높인다. 낯선환경에서도 유용하게 쓰일 가능성이 있기 때문이다.
- 큰 시스템을 제작하는 난이도를 낮춰준다.
정보은닉을 위한 장치 : 접근제한자 사용
모든 클래스와 멤버의 접근성을 가능한 한 좁혀야 한다.
- 소프트웨어가 올바로 동작하는 한 항상 가장 낮은 접근 수준을 부여해야 한다.
- 해당 책에 표현되는 package-private는 default 이다.
- (가장 바깥이라는 의미의) 톱레벨 클래스와 인터페이스에 부여할 수 있는 접근수준은 package-private와 public 두 가지다. 톱레벨 클래스나 인터페이스에 public으로 선언하면 공개 API가 되며, package-private으로 선언하면 해당 패키지 안에서만 이용할 수 없다. 패키지 외부에서 쓸 이유가 없다면 package-private으로 선언하자.
- 클래스의 공개 API를 설계한 후, 그 외 모든 멤버는 private으로 만들자. 그런 다음 오직 같은 패키지의 다른 클래스가 접근해야 하는 멤버에 한하여 package-private으로 풀어주자. private과 package-private멤버는 모두 공개 API에 영향을 주지 않는다.
- 멤버접근성을 방해하는 한가지 제약 : 상위클래스 메서드를 재정의하는 경우, 접근수준을 상위클래스보다 같거나 넓게 설정해야 한다.
- public 클래스의 인스턴스 필드는 되도록 public이 아니어야 한다 (아이템 16). public 가변 필드를 갖는 클래스는 일반적으로 스레드 안전하지 않다.
- 상수라면 public static final필드로 공개해도 좋지만, 배열필드를 두거나 이 필드를 반환하는 접근자 메서드는 제공하면 안된다.
자바9에서는 모듈 시스템이라는 개념이 도입되면서 두 가지 암묵적 접근 수준이 추가되었다.
모듈은 패키지들의 묶음이다.
- 모듈에 속하는 패키지 중 공개(export)할 것들을 선언한다. protected 혹은 public 멤버라도 해당 패키지를 공개하지 않았다면 모듈 외부에서는 접근할 수 없다. 모듈 안에서는 exports로 선언했는지 여부에 아무런 영향을 받지 않는다.
- 패키지 안에 있는 public 클래스의 public 혹은 protected멤버이다. 이 암묵적 접근 수준들은 각각 public수준과 protected 수준과 같으나, 그 효과가 모듈 내부로 한정되는 변종인 것이다. 이런 형태로 공유해야 하는 상황은 흔하지 않다. 그래야 하는 상황이 벌어지더라도 패키지들 사이에서 클래스들을 재배치하면 대부분 해결된다.
- 모듈을 사용하기 위해서는 패키지들을 모듈 단위로 묶고, 모듈 선언에 패키지들의 모든 의존성을 명시한다. 그런 다음 소스 트리를 재배치하고, 모듈 안으로부터 일반 패키지로의 모든 접근에 특별한 조치를 취해야 한다.. 그러니 꼭 필요한 경우가 아니라면 당분간은 사용하지 않는게 좋다.
정리
프로그램 요소의 접근성은 가능한 한 최소한으로 하라. 꼭 필요한 것만 골라 최소한의 public API를 설계하자. 그 외에는 클래스, 인터페이스, 멤버가 의도치 않게 API로 공개되는 일이 없도록 해야한다. public클래스는 상수용 public static final 필드 외에는 어떠한 public 필드도 가져서는 안 된다. public static final 피드가 참조하는 객체가 불변인지 확인하라.
'Algorithm Study' 카테고리의 다른 글
아이템17. 변경 가능성을 최소화하라 (0) | 2022.06.24 |
---|---|
아이템16. public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라 (0) | 2022.06.24 |
[스프링/Spring] Port 8080 is already in use 에러 해결 방법 (Mac) (0) | 2022.06.17 |
[프로그래머스] 위장 (level.2) / 해시/ JAVA (0) | 2022.06.16 |
[프로그래머스] 전화번호목록(level.2) / 해시 / JAVA (0) | 2022.06.15 |