자바/모던 자바 인 액션

[모던 자바 인 액션] 14장. 자바 모듈 시스템

Rudtjs 2023. 3. 5. 22:50

압력: 소프트웨어 유추

지금까지는 이해하고 유지보수하기 쉬운 코드를 구현하는 데 사용할 수 있는 새로운 언어 기능을 살펴봤다.

하지만 이러한 부분은 저수준의 영역에 해당하며, 소프트웨어 아키텍처에 해당하는 고수준의 영역에서는 생산성을 높일 수 있도록 추론하기 쉬운 소프트웨어 프로젝트가 필요하다.

  • 관심사 분리
  • 정보 은닉

관심사 분리

관심사 분리는 컴퓨터 프로그램을 고유의 기능으로 나누는 동작을 권장하는 원칙이다.

모델, 뷰, 컨트롤러 같은 아키텍처 관점 그리고 비즈니스 로직과 분리 등 수준 접근에 용이하고 다음과 같은 장점들이 더 있다.

  • 개별 기능을 따로 작업할 수 있으므로 팀이 쉽게 협업할 수 있다.
  • 개별 부분을 재사용하기 쉽다.
  • 전체 시스템을 쉽게 유지보수할 수 있다.

정보 은닉

정보 은닉은 세부 구현을 숨기도록 장려하는 원칙이다.

캡슐화된 코드는 다른 부분과 고립되어 있어 내부적인 변화가 의도치않게 영향을 미칠 가능성이 줄어든다. 자바에서는 private 키워드를 기준으로 캡슐화를 확인할 수 있다.

 

 자바 모듈 시스템을 설계한 이유

 모듈화의 한계

자바 9 이전까지는 모듈화된 소프트웨어 프로젝트를 만드는데 한계가 있었다. 자바는 클래스, 패키지, JAR 세 가지 수준의 코드 그룹화를 제공하는데, 이 중 패키지와 JAR 수준에서는 캡슐화가 거의 지원되지 않았다.

 

제한된 가시성 제어

한 패키지의 클래스와 인터페이스를 다른 패키지로 공개하려면 public으로 선언해야 한다. 결과적으로 이들 클래스와 인터페이스가 모두 공개되고, 사용자가 이 내부 구현을 마음대로 사용할 수 있게 된다.

public이므로 내부 구현을 마음대로 사용할 수 있게 되버린다. 보안 측면에서 코드가 노출이 되므로 위협에 많이 노출 된다.

 

클래스 경로

자바에서는 클래스를 모두 컴파일 한 다음 JAR 파일에 넣고 클래스 경로(class path)에 이 JAR 파일을 추가하여 번들로 사용할 수 있다.

이러한 클래스 경로와 JAR 조합에는 몇 가지 약점이 존재한다.

  • 클래스 경로에는 같은 클래스를 구분하는 버전 개념이 없다. 예를들어 파싱 라이브러리의 JSONParser 클래스를 지정할 때 버전 1.0인지 2.0인지 지정할 수 없으므로 클래스 경로에 두 버전의 같은 라이브러리가 존재하면 어떤 문제가 발생할 지 예측할 수 없다.
  • 클래스 경로는 명시적인 의존성을 지원하지 않는다. 한 JAR가 다른 JAR에 포함된 클래스 집합을 사용한다고 명시적으로 의존하지 않기 때문에 누락된 JAR를 확인하기 어렵고, 충돌이 발생할 수 있다.

거대한 JDK

자바 개발 키트(JDK)는 자바 프로그램을 만들고 실행하는 데 도움을 주는 도구의 집합이다.

시간이 흐르면서 JDK의 크기가 커졌고, 모바일이나 JDK 전부를 필요로 하지 않는 클라우드 환경에서 문제가 되었다.

또한 자바의 낮은 캡슐화 지원 때문에 JDK의 내부 API가 외부에 공개되었고, 여러 라이브러리에서 JDK 내부 클래스를 사용했다. 결과적으로 호환성을 깨지 않고는 관련 API를 바꾸기 어려운 상황이 되었다.

 

이런 문제들 때문에 JDK 자체도 모듈화할 수 있는 자바 모듈 시스템 설계의 필요성이 제기되었다.

즉 JDK에서 필요한 부분만 골라서 사용하고, 클래스 경로를 쉽게 유추할 수 있으며, 플랫폼을 진화시킬 수 있는 강력한 캡슐화를 제공할 새로운 건축 구조가 필요했다.

 

자바 모듈: 큰그림

자바 8에서는 모듈이라는 새로운 자바 프로그램 구조 단위를 제공한다.

모듈은 module 이라는 새 키워드에 이름과 바디를 추가해서 정의한다.

exports: 패키지명, requires: 모듈명 구조로 되어 있다.