buckapl
|--- domain
| |----- Account
| |----- Activity
| |----- AccountRepository
| |----- AccountService
|--- persistence
| |----- AccountRepositoryImpl
|--- web
| |----- AccountController
문제1 : 애플리케이션의 기능 조각(functional slice) 이나 특징(feature) 을 구분 짓는 패키지 경계가 없다
문제2 : 애플리케이션이 어떤 유스케이스들을 제공하는지 파악할 수 없다.
문제3 : 패키지 구조를 통해서는 우리의 목표로 하는 아키텍처를 파악할 수 없다.
buckpal
|-- account
|-- Account
|-- AccountController
|-- AccountRepository
|-- AccountRepositoryImpl
|-- SendMoneyService
SendMoneyService
와 같이 송금하기 기능을 구현한 클래스를 클래스명으로 바로 찾을 수 있다.(소리치는 아키텍처)buckpal
|-- account
|-- adapter
| |-- in
| | |-- web
| | |-- AccountController
| |-- out
| | |-- persistence
| | |-- AccountPersistenceAdapter
| | |-- SpringDataAccountRepository
|-- domain
| |-- Account
| |-- Activity
|-- application
|-- SendMoneyService
|-- port
|-- in
| |-- SendMoneyUseCase
|-- out
| |-- LoadAccountPort
| |-- UpdateAccountStatePort
장점1 : 이러한 패키지 구조는 모델-코드 갭(아키텍처-코드 갭)을 효과적으로 다룰 수 있다.
모델-코드 갭(model-code gap) 아키텍처 모델에는 항상 코드에 매핑할 수 없는 추상적인 개념, 기술 선택 및 설계 결정이 혼합되어 있다. 최종 결과는 모델이 정한 구성 요소의 배열과 반드시 일치하지 않는 소스 코드가 될 수 있다.
장점2 : 패키지간 접근을 제어할 수 있다.
SendMoneyUseCase
, LoadAccountPort
, UpdateAccountStatePort
Account
, Activity
GetAccountBalanceService
장점3 : 어댑터 코드를 자체 패키지로 이동시키면 필요시 하나의 어댑터를 다른 구현으로 쉽게 교체할 수 있다.
장점4 : DDD 개념에 직접적으로 대응할 수 있다.
클린 아키텍처의 본질적인 요건
이를 지키기 위해 의존성 역전 원칙을 사용한다.
AccountController
SendMoneyUseCase
인터페이스가 필요하므로 의존성 주입을 통해 SendMoneyService
클래스의 인스턴스를 주입SendMoneyService
LoadAccount
인터페이스로 가장한 AccountPersistenceAdapter
클래스의 인스턴스 주입
잘 정리하셨네요 ! 참고가 되었습니다 !!