1. 개요
클린 아키텍처를 대해 공부하면서 알게 된 주요한 분리 방식 두 가지가 있다.
첫 번째는 계층 우선 분리고, 두 번째는 기능 우선 분리이다.
먼저 계층 우선 분리는 기능보다는 계층에 따라 폴더를 나누는 방식으로 각 계층별 책임이 명확하다는 장점이 있다.
하지만 기능이 추가됨에 따라 관련 파일들이 여기저기 흩어지기 때문에 파일들을 추적하거나 관리하기가 쉽지 않다.
반면 기능 우선 분리는 기능을 기준으로 폴더를 나누는 방식으로 특정 기능과 관련된 모든 코드가 한 곳에 있어 유지보수가 용이하고, 모듈화, 리팩토링, 테스트가 쉽다는 장점이 있지만, 폴더가 많아진다는 단점도 있다.
이전 러닝 앱을 구현하였을 때 크게 4가지 기능(로그인, 지도에 위치 표시, 채팅, 러닝 결과 계산)이 있었다.
당시에 계층 우선 분리로 분리를 하였지만 코드 구조가 복잡하고 관리하기 어렵다는 단점을 느꼈다.
이러한 경험을 바탕으로 기존의 계층 우선 분리 방식에서 기능 우선 분리 방식으로 구조를 구성하게 되었다.
2. api 문서
https://developer.themoviedb.org/reference/intro/getting-started
3. 요구사항
1) HomePage
HomePage는 총 5개의 영화 리스트를 보여준다.
- 가장 인기 있는 영화(1개)
- 현재 상영중인 영화
- 인기있는 영화
- 평점 높은 영화
- 개봉 예정 영화
2) DetailPage
HomePage에서 클릭한 영화에 대한 상세 정보를 보여준다.
- 영화 포스터
- 영화 이름
- 개봉일
- 설명
- 흥행 정보
- 제작 회사
4. 프로젝트 구조 설정
HomePage와 DetailPage 두 화면 모두 영화 정보를 가져와서 표시하기 때문에 하나의 기능으로 묶었다.
feature / home 폴더를 만들고 그 안에 data, domain, presentation 등 계층 구조를 분리하여 정리하였다.
lib/
├── feature/ # 기능 단위로 나눈 구조
│ └── home/ # '홈' 도메인의 모든 코드
│ ├── core/ # 홈 기능에 한정된 공통 상수
│ │ ├── constants/ # 포스터 URL 등
│ │ └── poster_base_url.dart
│ │
│ ├── data/ # 외부 데이터 소스 (API, Provider 등)
│ │ ├── dtos/ # TMDB API 응답 모델 정의
│ │ ├── providers/ # 데이터 계층의 Provider
│ │ ├── repositories/ # 데이터 구현체 (Repository Impl)
│ │ └── services/ # TMDB API 호출 서비스
│ │
│ ├── domain/ # 비즈니스 로직 계층
│ │ ├── entities/ # 핵심 Entity 정의
│ │ ├── providers/ # 유스케이스 Provider
│ │ ├── repositories/ # 추상화된 Repository 인터페이스
│ │ └── usecases/ # UseCase 클래스
│ │
│ └── presentation/ # UI 및 상태 관리 계층
│ ├── detail/ # 영화 상세 화면
│ │ ├── widgets/ # 상세 화면용 위젯
│ │ └── detail_page.dart
│ │
│ ├── home/ # 홈 화면
│ │ └── widgets/ # 홈 UI 구성 위젯
│ │
│ ├── providers/ # ViewModel Provider 정의
│ └── viewmodels/ # ViewModel 정의
│
└── main.dart # 앱 진입점
5. 작성해야 할 파일
- DTO 설계 : TMDB 응답을 기반으로 모델 정의
- Service 인터페이스 및 구현체 : API 호출
- Service Provider : Riverpod 기반 상태 주입
- Entity 정의 : 도메인 모델 정의
- Repository 인터페이스 및 구현체 : 비즈니스 로직과 데이터 연결
- Repository Provider : 의존성 관리
- Usecase : 도메인 로직 캡슐화
- ViewModel : UI와 비즈니스 로직 사이에서 상태 관리
- ViewModel Provider : 의존성 관리
- UI : 사용자에게 표시
6. 회고
기능 우선 분리를 적용하여 개발을 진행했다.
현재는 기능이 많지 않아 기능 우선 분리에 대한 장점이 크게 와닿지는 않았지만,
기능이 추가되고 복잡해질수록 기능별 코드가 명확하게 분리되어 파일을 잘 관리할 수 있을 것 같다.
특히 기존에 경험했던 계층 우선 분리 방식에는 서로 다른 기능의 파일들이 여러 계층에 흩어져 있어 코드를 추적하는데 어려움이 있었지만, 하나의 기능과 관련된 모든 코드가 한 폴더 내에 모여있어 구조적으로 더 직관적이었다.
뿐만 아니라 Clean Architecture, MVVM, Riverpod 상태관리를 적용하면서 개념적으로 이해한 내용을 실전에서 적용해 보면서 의존성의 흐름과 역할 분리에 대해 더 이해할 수 있었다.
아직 완벽하게 익숙하진 않지만 반복적으로 적용해보며 더 자연스럽게 사용할 수 있도록 연습해야겠다고 느꼈다.
'Flutter' 카테고리의 다른 글
| [Flutter] mocktail Bad state: A test tried to use `any` or `captureAny` on a parameter of type 오류 해결 트러블슈팅 (1) | 2025.06.29 |
|---|---|
| [Flutter] TMDB로 영화관 앱 만들기 (0) | 2025.05.15 |
| [Flutter] mocktail을 이용하여 Unit Test 하기 (mockito vs mocktail) (0) | 2025.05.08 |
| [Flutter] 앱 테스트 유형 (feat. Integration, Unit, Widget) (0) | 2025.05.07 |
| [Flutter] Riverpod으로 상태관리하고, MVVM패턴 적용해서 Counter앱 만들기 (0) | 2025.05.02 |