1. Clean Architecture 기본 개념
- 3개 레이어: Presentation (UI 로직) → Domain (비즈니스 로직) ← Data (데이터 접근)
- 의존성 규칙: 내부 레이어는 외부 레이어에 의존하지 않음
- 핵심: 비즈니스 로직을 UI/DB로부터 완전히 독립시키는 것
2. Domain Layer 상세 분석
// Domain Layer 구성
📁 Entities (비즈니스 모델)
- Movie.swift
- MovieQuery.swift
📁 UseCases (비즈니스 로직)
- SearchMoviesUseCase.swift
- FetchRecentMovieQueriesUseCase.swift
📁 Interfaces/Repositories (의존성 역전)
- MoviesRepository.swift (Protocol)
- MoviesQueriesRepository.swift (Protocol)
UseCase의 역할:
- ✅ 비즈니스 규칙 구현 (검색 성공시 검색어 저장 등)
- ✅ 데이터 검증 및 변환
- ✅ 여러 Repository 조합
- ❌ 데이터 가져오기는 Repository가 담당
왜 Result<[Entity], Error>를 사용하나?
- Swift 표준 비동기 에러 처리 패턴
- 성공/실패를 명확히 구분
- 컴파일 타임 안전성 제공
3. Presentation Layer (MVVM)
// 역할 분담
🧠 ViewModel: "무엇을 보여줄지" 결정
- UI 상태 관리 (로딩, 에러, 데이터)
- 비즈니스 로직 연결 (UseCase 호출)
- UIKit 독립적
🎮 ViewController: "어떻게 연결할지" 결정
- View ↔ ViewModel 바인딩
- 사용자 입력을 ViewModel에 전달
- ViewModel 상태 변화를 UI에 반영
📱 View: "어떻게 보여줄지" 결정
- 순수한 데이터 표시
- 기본적인 UI 상호작용
데이터 흐름:
사용자 입력 → ViewController → ViewModel → UseCase → Repository → API
결과 반환 ← ViewController ← ViewModel ← UseCase ← Repository ← API
4. Data Layer - DTO의 필요성
왜 DTO가 필요한가?
- API 응답 구조 ≠ 앱의 비즈니스 모델
- 데이터 변환과 검증 역할
// API 응답 (DTO)
{
"id": 550,
"genre_ids": [18, 53, 35],
"release_date": "1999-10-15"
}
// 앱 모델 (Entity)
Movie(
id: "550", // Int → String
genre: .drama, // [18,53,35] → Genre enum
releaseDate: Date() // "1999-10-15" → Date
)
DTO의 장점:
- API 변경에 대한 격리
- 불필요한 데이터 제거
- 타입 안전성 보장
5. Clean Architecture의 단점
성능 문제:
- 메모리 사용량 증가
- 데이터 4번 변환 (JSON → DTO → Entity → ViewModel → UI)
복잡성 문제:
- 간단한 기능도 7-10개 파일 필요
- 높은 학습 곡선
- 프로토타입/MVP에 부적합
작은 프로젝트엔 적합하지 않음
6. Method Dispatch와 성능
- Static (가장 빠름): 컴파일 타임 결정, 인라이닝 가능
- Dynamic (느림): 런타임 V-Table 룩업
Clean Architecture의 성능 이슈:
// 🐌 Protocol = Dynamic Dispatch (3.75배 느림)
let useCase: SearchMoviesUseCase = DefaultSearchMoviesUseCase()
useCase.execute() // 런타임에 실제 구현체 찾아야 함
// 🚀 Concrete Type = Static Dispatch
let useCase = DefaultSearchMoviesUseCase()
useCase.execute() // 컴파일 타임에 결정
성능 최적화 방법:
// ✅ final 키워드
final class DefaultRepository: MoviesRepository { }
// ✅ private 메서드 (항상 Static)
private func internalLogic() { }
// ✅ Struct 사용
struct ValueTypeService { }
- 성능 최적화 부분은 관련 떱떱디씨 영상과 함께 추후에 자세히 정리 예정..!
https://tech.olx.com/clean-architecture-and-mvvm-on-ios-c9d167d9f5b3
Clean Architecture and MVVM on iOS
When we develop software it is important to not only use design patterns, but also architectural patterns. There are many different…
tech.olx.com
'iOS' 카테고리의 다른 글
[iOS] Unit Test 기본 개념과 적용 (0) | 2025.06.23 |
---|---|
[iOS] MVVM 패턴에서 데이터 로딩 책임 분리 (0) | 2025.06.18 |
[Swift] SOLID 원칙 iOS에 적용해보기 (1) | 2025.06.10 |
[iOS] 리팩토링이라 쓰고 파일분리노가다라고 읽기 (0) | 2025.05.22 |
override init vs required init 초기화 차이 (0) | 2025.05.21 |