10. 아키텍처 경계 강제하기

일정 규모 이상의 모든 프로젝트는 시간이 지나면서 서서히 무너지게 된다. 계층 간의 경계가 약화되고, 코드는 점점 테스트하기 어려워지고, 새로운 기능을 구현하는데 점점 더 많은 시간이 든다. 그러므로 아키텍처 내의 경계를 강제하고, 붕괴에 맞서 싸우기 위한 몇 가지 조치를 알아보도록 하자.

경계와 의존성

아래의 그림에서는 아키텍처의 요소들이 어느 계층에 있는지를 보여준다. 가장 안쪽에는 도메인 엔티티가 있다. 애플리케이션 계층은 서비스 안에서 유스케이스를 구현하기 위해 도메인 엔티티에 접근한다. 어댑터는 인커밍 포트를 통해 서비스에 접근하고, 반대로 서비스는 아웃고잉 포트를 통해 어댑터에 접근한다. 마지막으로 설정 계층은 어댑터와 서비스 객체를 생성할 팩토리를 포함하고 있고, 의존성 주입 메커니즘을 제공한다.

Untitled

아키텍처의 경계는 각 계층 사이, 안쪽 인접 계층과 바깥쪽 인접 계층 사이에 경계가 있다. 그리고 의존성 규칙에 따르면 계층 경계를 넘는 의존성은 항상 안쪽으로 향해야 한다.

이번에는 이를 강제하는 방법들을 알아보는 것이다.

접근 제한자

경계를 강제하기 위해 자바에서 사용가능한 가장 기본적인 도구는 접근제한자이다.

package-private(default) 제한자는 같은 패키지 내의 클래스들은 서로 접근 가능하지만, 바깥 패키지에서는 접근할 수 없다. 패키지를 통해 클래스들을 응집력있게 만들어준다. 이를 통해 의존성이 잘못된 방향을 가리켜서 위반하지 못하도록 할 수 있다.

예를 들어 영속성 어댑터와 같은 애들은 포트를 통해 접근하므로 package-private으로 만들 수 있다. 단 이것은 클래스 패스 스캐닝을 이용해야만 가능하다.

package-private은 가장 효과적이지만 패키지 내의 클래스가 특정 개수를 넘어가기 시작하면 쉽게 코드를 찾도록 하위 패키지를 만들게 된다. 하지만 자바에서는 하위 패키지 역시 다른 패키지로 취급하므로 접근이 불가능해지는데, 이때 public으로 접근제어자가 바뀌면서 의존성 규칙이 깨질 수 있는 환경이 된다.

컴파일 후 체크