본문 바로가기
개인 공부/Java (이펙티브 자바)

[이펙티브 자바] 아이템 15 : 클래스와 멤버의 접근 권한을 최소화하라

by 희조당 2023. 2. 8.
728x90

🎯 학습 목표

  • 접근 권한을 최소화 (feat. 캡슐화)
  • package-private
  • @NoArgsConstructor와 접근 범위

📌 접근 권한을 최소화?

Java를 공부한 사람이라면 접근 권한을 보자마자 접근 지정자를 떠올렸을 것이다.

그냥 읽으면 다 흡수하지 못할 내용들이다. 이번 아이템을 통해서 캡슐화를 다시 공부해 보자.

😎 캡슐화? 그거 알긴 알지

우리가 공부하는 Java가 OOP란 사실은 누구나 안다. 또한, 캡슐화가 무엇인지도 알고 있다.

잘 공부한 사람이라면 이번 내용을 읽고 한 번에 이해가 되거나 와닿았을 것이다.

근데 나는 아니니까 다시 공부했다. 🥲🥲


💊 캡슐화

캡슐화란? 연관된 속성과 기능을 하나의 캡슐로 만들어 데이터를 외부로부터 보호하는 것을 말한다.

객체지향에선 "묻지 말고 시켜라" (Tell, Don't Ask!)라는 말이 캡슐화를 지키기 위한 가장 기본이라고 생각한다.

그렇다면 책에서 말하는 장점들이 무엇을 말하는 것일까?

😋 캡슐화의 장점들

  • 병렬로 개발할 수 있어 시스템 개발 속도를 높아진다.
  • 시스템 관리 비용을 낮춘다.
  • 성능 최적화에 도움을 준다.
  • 소프트웨어 재사용성을 높인다.
  • 큰 시스템을 제작하는 난이도를 낮춰준다.

우선 '병렬로 개발할 수 있다'라는 말이 무엇일까?

A가 개발이 끝나지 않아도 A를 의존하는 B를 개발할 수 있다는 뜻이다. 

내부 로직은 없는 깡통 메서드여도 메서드 자체는 호출이 가능하기 때문에, B는 그 점을 감안하고 개발을 할 수 있다.

 

이후 다른 장점들은 캡슐화 자체보다는 객체지향 프로그래밍(OOP)에 관한 이야기로 받아들였다.

캡슐화가 잘 이루어졌다면 자연스럽게 결합도가 떨어질 것이고 코드는 당연히 유연해질 것이다.

추가적인 요구사항이 발생했을 때 쉽게 수정할 수 있고 최적화 등에 도움이 될 것이다.


🧐 요약과 package-private

책에서 이야기하는 내용은 다음과 같이 요약할 수 있다.

  • public으로 공개되는 객체는 하위호환 때문에 지속적인 관리를 요한다. 따라서 접근 범위를 잘 정해야 한다.
  • 단순히 테스트를 위해서 접근 범위를 바꾸면 안 된다.
  • public 클래스의 필드는 public이 아니여야 한다.
  • 클래스의 상수는 기본 타입이나 불변 객체만을 참조해야 한다.

🤔 package-private

책에서는 계속 package-private을 사용해서 필요한 범위까지 접근을 제한시키라고 했다.

이 접근지정자를 많이 사용한 적이 없는 것 같아서 좀 자세하게 찾아봤다.

👍 사용 추천! (참고)

추천하는 이유는 java.util.*을 예로 들었다. 큰 라이브러리나 오픈 소스의 경우를 말한다.

패키지의 다른 클래스에서만 액세스 할 수 있도록 메서드나 필드를 제한함으로써 구현 세부 정보를 최대한 적게 노출하려는 의도인 것이다. 

말 그대로 캡슐화를 적극 활용하는 의도인 것이다.

👎 사용 비추천! (참고)

반대로 추천하지 않는 이유는 실제 개발 기간에는 패키지 구조가 빈번하게 변할 수 있다는 점이다.

빈번한 변화는 수정을 야기하고 결국 비용이 늘어남을 의미한다.

좋은 방법임이 분명하지만 현실적으로 100% 활용하기는 어렵다는 점이다.

 

양쪽의 의견을 들어봤을 때 상황에 맞게 사용하는 것이 중요하다는 생각이 든다.

이미 좋은 예시가 존재하고 잘 활용하면 좋겠지만, 기능이 점점 많아진다면 아무래도 사용하기 어렵지 않을까?


🤔 @NoArgsConstructor와 접근 범위

다른 프로젝트의 코드를 구경하다가 생성자의 접근 범위를 제한하는 것을 많이 봤다.

왜 그리고 어떻게 사용하는지 몰라서 한번 정리해본다!

🧐 왜 사용할까?

접근 제한을 통해서 지정한 생성자(혹은 방식)을 강제하기 위함이다.

이렇게하면 컴파일 단계에서 확인할 수 있고, 지정된 방식만 사용하니 객체의 불변성을 보장할 수 있다.

 

보통 Lombok의 Builder를 사용해서 인스턴스를 생성한다.

Builder를 사용하기 위해서는 모든 필드를 받는 생성자가 필요한데, @Builer를 붙이면 모든 필드를 받는 Inner Class가 생성되고 이 클래스에서 인스턴스를 생성해서 넘겨주는 것이다.이렇게 되면 기본 생성자를 사용하지 않게되지만 여전히 기본 생성자로 객체 생성할 수 있어 항상 불변한 객체임을 보장할 수 없다.

 

제한 레벨은 다양하게 package, module, protected, private 등 다양하게 제공된다.

따라서, 알맞게 정해서 사용하자 😋😋


-Reference

https://softwareengineering.stackexchange.com/questions/294640/is-java-package-level-scope-useful

https://dev.to/cauchypeano/why-you-should-avoid-package-private-scope-in-java-anl

 

😋 지극히 개인적인 블로그지만 훈수와 조언은 제 성장에 도움이 됩니다 😋

댓글