(0) 애플리케이션 개발 표준
팀에서는 몇가지 이유로 애플리케이션 개발 표준을 수립한다.
- 코드 품질과 일관성 확보
- 협업 효율성 향상
- 유지보수성 확보
- 개발속도 향상
- 의사결정 비용 절감
예를 들어, architecture을 구성하는 요소들의 layer, 네이밍, 의존관계에 대한 규칙을 정의한다.

(1) 애플리케이션 개발 표준의 한계
초기에는 애플리케이션 개발 표준이 잘 지켜질 수 있다. 그러나 예외 케이스가 나와서 표준이 변경되거나, 조직 구성원에 변화가 생기게 되면 이를 지키기 어려워진다. 모든 구성원들이 지난 히스토리를 기억하며 애플리케이션을 개발하는 데에는 한계가 있기 때문이다.
그 영향으로 애플리케이션에서 서로 다른 이름 패턴을 사용하고, 패키지 구성과 의존관계가 일정하지 않은 문제가 발생하게 된다.
(2) ArchUnit이란?
archunit은 Java 아키텍처 테스트 라이브러리이다. 코드의 구조적 규칙과 아키텍처 원칙을 자동화된 테스트로 검증할 수 있게 해준다. 이를 사용하면 다음과 같은 이점을 얻을 수 있다.
아키텍처 규칙 검증
- 패키지 간의 의존성 규칙 (예: Controller는 Service만 호출해야 함)
- 레이어 아키텍처 준수 여부
- 순환 의존성 검출
코딩 규칙 강제
- 특정 어노테이션 사용 규칙
- 클래스 네이밍 컨벤션
- 메서드 접근 제한자 규칙
ArchUnit 테스트는 일반적인 단위 테스트처럼 실행된다. 아키텍처 규칙이 위반되면 테스트가 실패한다. 이를 통해 팀 내 코딩 표준을 자동으로 유지할 수 있다.
(3) 적용 예시
4 layered architecture에서 의존할 수 있는 레이어 (==패키지)를 정의한 사례를 살펴보자.
JavaClasses importedClasses = new ClassFileImporter().importPackages("com.americanopeople");
@Test
public void four_layer_architecture_should_be_respected() {
layeredArchitecture()
.layer("Interfaces").definedBy("..interfaces..") // definedBy은 패키지 경로 패턴을 뜻한다.
.layer("Application").definedBy("..application..")
.layer("Domain").definedBy("..domain..")
.layer("Infrastructure").definedBy("..infrastructure..")
.whereLayer("Interfaces").mayNotBeAccessedByAnyLayer()
.whereLayer("Application").mayOnlyBeAccessedByLayers("Interfaces")
.whereLayer("Domain").mayOnlyBeAccessedByLayers("Application")
.whereLayer("Infrastructure").mayOnlyBeAccessedByLayers("Domain")
.check(importedClasses);
}
이는 4가지 규칙을 선언한 것이다.
- Interface을 의존하는 서비스는 없어야 한다.
- Application은 Interface Layer만 의존할 수 있다.
- Domain은 Application Layer만 의존할 수 있다.
- Infra는 Domain Layer만 의존할 수 있다.
예를 들어, Interface Layer에 속하는 Controller가 Infra Layer에 속하는 Repository에 직접 접근하는 것을 UnitTest으로 검증하고 제어할 수 있다.
그외 샘플 코드는 github.com/TNG/ArchUnit을 참고하자.
(4) 활용
github PR hook action 등을 활용하여 CI TestCode 자동화를 적용해두면, 아키텍처 규칙이 잘 적용되는지 자동으로 검증할 수 있다.
(5) 참고
배달의민족 기술블로그 - 전체 서비스를 관통하는 도메인 모듈을 안전하게 분리하기: 헥사고날 아키텍처와 ArchUnit 도입
'소프트웨어-이야기 > 단어사전' 카테고리의 다른 글
| 2025년 09월 복습장 (0) | 2025.09.24 |
|---|---|
| prompt injection: 바이브코딩과 신규 보안 취약점 (0) | 2025.06.27 |
| Claude Code (0) | 2025.06.27 |