본문 바로가기
Theory/Architecture

아키텍처 경계 강화하기

by y.j 2022. 7. 11.
728x90

경계와 의존성

경계를 강화한다는 것은 어떤 의미일까? 의존성을 항상 안쪽으로 흐르게 하는 것이다.

빨간선으로 되어 있는 잘못된 방향을 없애 경계를 강화해야 한다.

 

접근 제한자

package-private 제한자는 상당히 중요하다. 다른 패키지에서 접근하지 못하게 하며 모듈의 진입점만 public으로 하여 의존성 규칙을 위반할 위험을 줄어들게 만든다.

buckpal
        |--- account
            |--- adapter
            |    |--- in
            |    |    |--- web
            |    |         |--- o AccountController
            |    |--- out
            |    |    |--- persistence
            |    |    |    |--- o AccountPersistenceAdapter
            |    |    |    |--- o SpringDataAccountRepository
            |--- domain
            |    |--- + Account
            |    |--- + Activity
            |--- application
                    |--- o SendMoneyService
                    |--- port
                        |--- in
                        |    |--- + SendMoneyUseCase
                        |--- out
                             |--- + LoadAccountPort
                             |--- + UpdateAccountStatePort

o는 package-private을 의미하고 +는 외부에서 접근하는 진입점이거나 공유되는 객체이다. 

  • 도메인 패키지는 다른 계층에서 접근 할 수 있어야 한다.
  • application계층은 web어댑터와 persistence어댑터에서 접근 가능해야 한다.

 

컴파일 후 체크

public 제한자가 있으면 의존성의 방향이 잘못되었는지 컴파일러를 통해 확인하기 어렵다. 컴파일 후 체크를 통해 런타임에 의존성을 확인 한다. ArchUtil은 의존성 방향이 기대한 대로 잘 설정돼 있는지 체크할 수 있는 API를 제공한다. 의존성 규칙 위한을 발견하면 예외를 던지며 Junit과 같은 단위 테스트 프레임워크 기반에서 가장 잘 동작한다.

 

  • ArchUnit으로 계층 간의 의존성을 체크 할 수 있다. 아래코드 domain에서 application으로 향하는 의존성이 있는지 없는지 체크 한다.
@Test
void testPackageDependencies() {
   noClasses()
         .that()
         .resideInAPackage("io.reflectoring.reviewapp.domain..")
         .should()
         .dependOnClassesThat()
         .resideInAnyPackage("io.reflectoring.reviewapp.application..")
         .check(new ClassFileImporter()
               .importPackages("io.reflectoring.reviewapp.."));
}
  • 패키지 사이의 의존성을 확인 할 수 있다.
@Test
void validateRegistrationContextArchitecture() {
   HexagonalArchitecture.boundedContext("io.reflectoring.buckpal.account")

         .withDomainLayer("domain")

         .withAdaptersLayer("adapter")
         .incoming("in.web")
         .outgoing("out.persistence")
         .and()

         .withApplicationLayer("application")
         .services("service")
         .incomingPorts("port.in")
         .outgoingPorts("port.out")
         .and()

         .withConfiguration("configuration")
         .check(new ClassFileImporter()
               .importPackages("io.reflectoring.buckpal.."));
}

변수에 오타가 있다면 실패를 내보내지 않기 때문에 클래스를 하나도 찾지 못했을 때 실패하는 테스트를 추가해야 한다.

 

빌드 아티팩트

 

 

 

728x90

'Theory > Architecture' 카테고리의 다른 글

의식적으로 지금길 사용하기  (0) 2022.07.12
애플리케이션 조립하기  (0) 2022.07.10
경계 간 매핑하기  (0) 2022.07.09
아키텍처 요소 테스트하기  (0) 2022.07.05
영속성 어댑터 구현하기  (0) 2022.07.02

댓글