Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
Tags
- 백준 4949번
- 백준 5525번
- HTTP
- 모두의네트워크
- 모두를위한딥러닝
- 깃허브 토큰 인증
- 팀플회고
- 지네릭스
- SQL
- 정리
- 모두를 위한 딥러닝
- 리액트 네이티브 시작하기
- 깃허브 로그인
- 데이터베이스
- 깃 터미널 연동
- 문자열
- 자바
- 리액트 네이티브
- 깃 연동
- 백준 4358번
- 백준 4358 자바
- React Native
- 딥러닝
- 데베
- 네트워크
- 리액트 네이티브 프로젝트 생성
- 스터디
- 머신러닝
- 모두의 네트워크
- 백준
Archives
- Today
- Total
솜이의 데브로그
Chapter 3 ) 코드 구성하기 본문
Reference : 만들면서 배우는 클린 아키텍처
계층으로 구성하기
buckapl
|--- domain
| |----- Account
| |----- Activity
| |----- AccountRepository
| |----- AccountService
|--- persistence
| |----- AccountRepositoryImpl
|--- web
| |----- AccountController
- 웹 계층, 도메인 계층, 영속성 계층 각각에 대해 전용 패키지인 web, domain, persistence를 뒀다.
- 의존성 역전 원칙을 적용해 의존성이 domain 패키지에 있는 도메인 코드만을 향하도록 한다.
- domain 패키지에 AccountRepository 인터페이스를 추가
- persistence 패키지에 AccountRepositoryImpl 구현체를 두어서 의존성을 역전시킴
위 패키지 구조는 최적의 구조가 아니다.
- 애플리케이션의 기능 조각이나 특성을 구분짓는 패키지 경계가 없다.
- 애플리케이션이 어떤 유스케이스들을 제공하는지 파악할 수 없다
- 패키지 구조를 통해서는 우리가 목표로 하는 아키텍처를 파악할 수 없다.
기능으로 구성하기
buckapl
|--- account
| |----- Account
| |----- Activity
| |----- AccountRepository
| |----- SendMoneyService
| |----- AccountRepositoryImpl
| |----- AccountController
- 위 패키지는 계좌와 관련된 모든 코드를 최상위의 account 패키지에 넣고, 계층 패키지들을 없앴다.
- 패키지 외부에서 접근하면 안되는 클래스들에 대해 package-private 접근 수준을 이용해 패키지 간의 경계를 강화할 수 있다.
- 패키지 경계를 package-private 접근 수준과 결합해 각 기능 사이의 불필요한 의존성을 방지
- AccountService의 책임을 좁히기 위해 SendMoneyService로 클래스명 변경
단점
- 계층에 의한 패키지 방식보다 아키텍처의 가시성을 떨어뜨린다.
- 어댑터를 나타내는 패키지명이 없고, 인커밍 포트, 아웃고잉 포트를 확인할 수 없다.
- 도메인 코드와 영속성 코드 간의 의존성을 역전시켰음에도 package-private 접근 수준을 이용해 도메인 코드가 실수로 영속성 코드에 의존하는 것을 막을 수 없다.
아키텍처적으로 표현력 있는 패키지 구조
buckapl
|--- account
| |----- adapter
| | |----- in
| | | |---- web
| | | | |---- AccountController
| | |----- out
| | | |---- persistence
| | | | |---- AccountPersistenceAdapter
| | | | |---- SpringDataAccountRepository
| |---- domain
| | |----- Account
| | |----- Activity
| |---- application
| | |----- SendMoneyService
| | |----- port
| | | |---- in
| | | | |---- SendMoneyUseCase
| | | |---- out
| | | | |---- LoadAccountPort
| | | | |---- UpdateAccountStatePort
헥사고날 아키텍처에서 구조적으로 핵심적인 요소는 아래와 같다.
- 엔티티
- 유스케이스
- 인커밍/아웃고잉 포트
- 인커밍/아웃고잉 어댑터
구조의 각 요소들은 패키지 하나씩에 직접 매핑된다.
- 최상위에는 Account와 관련된 유스케이스를 구현한 모듈임을 나타내는 account 패키지
- 그 다음 도메인 모델이 속한 domian 패키지
- 도메인 모델을 둘러싼 서비스계층인 application 패키지
- SendMoneyService : 인커밍 포트 인터페이스인 SendMoneyUseCase 구현, LoadAccountPort와 UpdateAccountStatePort 사용
- adapter 패키지는 애플리케이션 계층의 인커밍 어댑터와 아웃고잉 어댑터를 포함
- 어댑터 패키지에 들어있는 모든 클래스들은 application 패키지 내에 있는 포트 인터페이스를 통하지 않고는 바깥에서 호출되지 않기 때문에 package-private 접근 수준으로 둬도 된다.
- 의도적으로 어댑터에서 접근 가능해야 하는 포트들은 public이어야 한다.
- 이 패키지 구조는 DDD 개념에 직접적으로 대응시킬 수 있다!
의존성 주입의 역할
- 클린 아키텍처의 가장 본질적인 요건은 애플리케이션 계층이 인커밍/아웃고잉 어댑터에 의존성을 갖지 않는 것이다.
- 모든 계층에 의존성을 가진 중립적인 컴포넌트를 하나 도입
- 이 컴포넌트는 아키텍처를 구성하는 대부분의 클래스를 초기화하는 역할을 한다.
느낀점
프로젝트 진행하면서 패키지 구조를 어떻게 가져가야할지 정말 많이 고민했고, 실제 진행하면서도 서비스 내에 기능이 너무 많아져서 곤란했는데 어느정도는 감이 온다!
그런데 아직 어댑터나 포트에 대해서는 이해가 잘 가지 않아서 실제 코드 구현하면서 더 살펴봐야할 것 같다.
'책을 읽자 > 만들면서 배우는 클린 아키텍처' 카테고리의 다른 글
Chapter 2 ) 의존성 역전하기 (0) | 2022.10.26 |
---|---|
Chapter 1 ) 계층형 아키텍처의 문제는 무엇일까? (0) | 2022.10.26 |