iOS - Swift
[iOS/Swift] Clean Architecture 의 이해
개발자 수니
2024. 5. 16. 17:02
728x90
반응형
Clean Architecture 의 이해
의존성 규칙
- 원 : 소프트웨어의 각기 다른 영역
- 외부에서 안쪽을 향해서만 의존한다. 내부에서 외부로는 종속성이 없다. ( -> 화살표가 의존성 규칙 )
Entities
- Enterpise Business Rules : 대규모 프로젝트 레벨의 비즈니스 규칙 캡슐화, Application의 비즈니스 객체
- 메서드를 갖는 객체, 데이터 구조, 함수의 집합
- Application의 동작에 관한 변경(페이지 내비게이션의 변경이나 보안 사항)에 영향을 받지 않아야 한다.
- 다른 계층의 어느 것도 포함하면 안된다.(의존성 규칙)
// iOS Clean Architecture MVVM Example 의 Entities
// GitHub: https://github.com/kudoleh/iOS-Clean-Architecture-MVVM
import Foundation
struct Movie: Equatable, Identifiable {
typealias Identifier = String
enum Genre {
case adventure
case scienceFiction
}
let id: Identifier
let title: String?
let genre: Genre?
let posterPath: String?
let overview: String?
let releaseDate: Date?
}
Use Cases
- Application Business Rules : Application 고유 비즈니스 규칙을 포함, 시스템의 모든 Use Cases를 캡슐화하고 구현
- Entities 흐름을 조합
- Use Cases의 변경이 Entities에 영향을 주지 않을 것을 기대하며 DataBase, UI 또는 공통 Framework의 변경으로부터 영향받지 않을 것을 기대한다. (의존성 규칙)
- 하지만, Application의 조직에 대한 변경은 Use Cases 영향이 있다. Use Cases의 상세가 바뀐다면 이 계층의 코드는 확실히 영향을 받는다.
- Entities를 제외한 다른 계층의 어느 것도 포함하면 안된다. (의존성 규칙)
// iOS Clean Architecture MVVM Example 의 Use Cases
// GitHub: https://github.com/kudoleh/iOS-Clean-Architecture-MVVM
import Foundation
protocol SearchMoviesUseCase {
func execute(requestValue: SearchMoviesUseCaseRequestValue,
cached: @escaping (MoviesPage) -> Void,
completion: @escaping (Result<MoviesPage, Error>) -> Void) -> Cancellable?
}
final class DefaultSearchMoviesUseCase: SearchMoviesUseCase {
private let moviesRepository: MoviesRepository
private let moviesQueriesRepository: MoviesQueriesRepository
init(moviesRepository: MoviesRepository,
moviesQueriesRepository: MoviesQueriesRepository) {
self.moviesRepository = moviesRepository
self.moviesQueriesRepository = moviesQueriesRepository
}
func execute(requestValue: SearchMoviesUseCaseRequestValue,
cached: @escaping (MoviesPage) -> Void,
completion: @escaping (Result<MoviesPage, Error>) -> Void) -> Cancellable? {
return moviesRepository.fetchMoviesList(query: requestValue.query,
page: requestValue.page,
cached: cached,
completion: { result in
if case .success = result {
self.moviesQueriesRepository.saveRecentQuery(query: requestValue.query) { _ in }
}
completion(result)
})
}
}
Controllers, GateWays, Presenters
- Interface Adapters
- Data : Entities나 Use Cases에 용이한 형식 > 사용하고 있는 Frame Work(Datatbase, Web 등)에 용이한 형식으로 변환
- 이 계층 내부(원 안)계층의 코드는 Database에 관해 아는 것이 없어야 한다.
Devices, Web, UI, DB, External Interfaces
- Frameworks & Driver
- Frame Work 도구로 구성 : Database, Web 등
- 내부(원 안)계층과 통신할 연결 코드 이외에는 별다른 코드를 작성하지 않는다.
Clean Architecture의 주의할 점
- 원의 경계를 넘나드는 Data는 단순한 구조로 이루어지게 한다.
- Entities와 Database Row을 그대로 전달하는 것은 의존성 규칙 위반이다. 안쪽의 원이 강제로 바깥쪽 원에 관한 것을 알아버리기 때문이다.
- 경계를 넘나드는 Data는 항상 안쪽의 원이 다루기 쉬운 형식이어야 한다.
Clean Architecture의 핵심
- 원의 가지수와 종류가 중요한 것이 아니다.
- 의존 규칙이 가장 중요! : 소스 코드의 의존성은 항상 안쪽으로 향해야 한다.
- 안쪽으로 향해감 : 추상회 수준은 올라간다. 캡슐화한다.
- 가장 바깥쪽의 원 : 저수준의 구체적인 상세 정보를 담는다.
By separating the software into layers, and conforming to The Dependency Rule, you will create a system that is intrinsically testable, with all the benefits that implies.
소프트웨어를 계층으로 나누고 의존성 규칙을 따름으로써 본질적으로 테스트하기 쉬운 시스템을 만들 수 있고 의존성 규칙이 가져오는 이점을 얻을 수 있다.
🙋🏻♀️ 참고
728x90
반응형