반응형

1. 서론

이번 포스팅에서는 Chapter14의 자바 모듈 시스템에 대해 진행하도록 하겠습니다.

 

2. 압력 : 소프트웨어 유추

일반적으로 자바 언어는 유지보수가 쉬운 언어라고 합니다.

 

그 이유는 관심사 분리, 정보 은닉의 특징을 제공하기 때문입니다.

 

1) 관심사 분리

 

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

 

관심사 분리의 장점은 아래와 같습니다.

 

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

이러한 관심사 분리를 도울도록 자바 8에서는 모듈 시스템을 제공하였습니다.

 

2) 정보 은닉

 

정보 은닉은 어떤 부분을 변경하였을 때, 다른 부분까지 영향을 미칠 가능성을 줄일 수 있게 합니다.

 

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

 

1) 모듈화의 한계

 

자바 9 이전에는 모듈화된 소프트웨어 프로젝트를 만드는데 한계가 있었습니다.

 

자바는 클래스, 패키지, jar 세 가지 수준의 코드 그룹화를 제공합니다.

하지만 패키지와 jar 수준에서 캡슐화를 거의 지원하지 못했습니다.

 

제한된 가시성 제어

 

자바는 클래스 단위에서는 private, protected, public 으로 가시성을 제공합니다.

하지만 패키지 단위에서는 제공하고 있지 않는것이 문제가 되었습니다.

클래스는 다르고, 같은 패키지에서만 공개하여 사용하고 싶은 경우
다른 패키지에서도 사용이 가능한 public으로 해야하기 때문입니다.

 

클래스 경로

 

자바에는 태생적으로 클래스 경로와 JAR 조합에 약점을 가지고 있습니다.

 

  1. 클래스 경로에는 같은 클래스를 구분하는 버전 개념이 없습니다.
  2. 클래스 경로는 명시적인 의존성을 지원하지 않습니다.
    1. 한 JAR가 다른 JAR에 포함된 클래스 집합을 사용하라는 명시적인 의존성을 지원하지 않는다는 의미입니다.

 

 

반응형

 

 

 

4. 자바 모듈 큰 그림

자바 8에서는 모듈이라는 새로운 구조 단위를 제공합니다.

 

모듈 디스크립터는 module-info.java 라는 특별한 파일에 저장되고, 보통 패키지와 같은 폴더에 위치합니다.

 

아래는 자바 모듈 디스크립터의 구조를 도식화 한것입니다.

 

 

5. 여러 모듈 활용하기

 

1) exports 구문

 

exports는 패키지 단위로 다른 모듈에서도 사용할 수 있도록 공개하는 키워드입니다.

 

아래는 한 모듈의 exports 예제입니다.

 

module expenses.readers {
    exports com.example.expenses.readers;
    exports com.example.expenses.readers.file;
    exports com.example.expenses.readers.http;
}

 

2) requires 구문

 

requires는 의존하고 있는 모듈을 지정하는 키워드입니다.

 

기본적으로 모든 모듈은 java.base 라는 모듈을 의존하고 있습니다.

때문에, 이 java.base는 생략가능하며, java.base 가 아닌 모듈을 의존하는 경우에 requires를 사용하면 됩니다.

 

3) 이름 정하기

 

모듈명의 경우 자바 8에서 새롭게 나온 개념으로 이름을 정하는 것에 대한 정확한 규칙이 없습니다.

다만, 오라클에서는 패키지명처럼 인터넷 도메인명을 역순으로 모듈의 이름을 정하도록 추천하고 있습니다.

 

6. 모듈 정의와 구문들

모듈 정의는 module-info.java 파일에 해야하며, 이 파일은 src/main/java 디렉터리에 있어야 합니다.

 

정의할때 사용하는 구문들은 위에서 살펴본 requires, exports 말고도,  requires-transitive, exports-to, open, opens, uses, provides 구문들이 있습니다.

 

1)  requires-transitive

 

이 구문은 다른 모듈이 제공하는 공개 형식을 한 모듈에서 사용할 수 있다고 지정할 수 있습니다.

 

아래는 예제입니다.

 

module com.iteratrlearning.ui {
    requires transitive com.iteratrlearning.core;

    exports com.iteratrlearning.ui.panels;
    exports com.iteratrlearning.ui.widgets;
}

module com.iteratrlearning.application {
    requires com.iteratrlearning.ui
}

 

결과적으로 application 모듈은 core에서 제공하는 공개 형식에 접근할 수 있습니다.

 

 

2) exports to

 

exports to 구문은 사용자에게 공개할 기능을 제한함으로 가시성을 좀 더 정교하게 제어할 수 있습니다.

 

아래는 예제 입니다.

 

module com.iteratrlearning.ui {
    requires com.iteratrlearning.core;

    exports com.iteratrlearning.ui.panels;
    exports com.iteratrlearning.ui.widgets to
            com.iteratrlearning.ui.widgetuser;
}

 

위 예제는 com.iteratrlearning.ui.widgets 에 접근 권한을 가진 사용지의 권한을 com.iteratrlearning.ui.widgetuser로 제한합니다.

 

 

3) open 과 opens

 

모듈 선언에 open 키워드를 사용하면 모든 패키지를 다른 모듈에 반사적으로 접근을 허용할 수 있습니다.

 

전체 모듈을 개발하지 않고도 opens 구문을 모듈 선언에 이용해 필요한 개별 패키지만 개방할 수 있습니다.

 

7. 마무리

 

이번 포스팅에서는 Chapter14 자바 모듈 시스템에 대해 진행하였습니다.

다음에는 Chapter15 CompletableFuture와 리액티브 프로그래밍의 컨셉의 기초에  대해 포스팅하겠습니다.

반응형

+ Recent posts