안쪽 layer은 바깥 layer에 의존성을 갖으면 안 됩니다.
의존성 방향
과, 데이터 흐름
을 표시한 그림입니다. Repository Interface(Protocol)을 사용하는 부분에서 의존성 역전
을 볼 수 있습니다.
View(UI)는 View Model(Presenter)로 부터 메소드를 실행합니다.
View Model은 Use Case를 실행합니다.
Use Case는 User와 Repository로 부터 data를 결합합니다.
각각의 Repository는 Remote Data(Network), Persistent DB 로 부터 데이터를 반환합니다.(Remote or Cached).
Repository에서 반환된 정보는 다시 View(UI)로 흘러갑니다.
protocol UseCase {
@discardableResult
func start() -> Cancellable?
}
Delegation과 Closure을 사용해서 소통합니다.
// Define Dependencies protocol for class or struct that needs it
protocol MoviesSearchFlowCoordinatorDependencies {
func makeMoviesListViewController() -> MoviesListViewController
}
class MoviesSearchFlowCoordinator {
private let dependencies: MoviesSearchFlowCoordinatorDependencies
init(dependencies: MoviesSearchFlowCoordinatorDependencies) {
self.dependencies = dependencies
}
...
}
// Make the DIContainer to conform to this protocol
extension MoviesSceneDIContainer: MoviesSearchFlowCoordinatorDependencies {}
// And inject MoviesSceneDIContainer `self` into class that needs it
final class MoviesSceneDIContainer {
...
// MARK: - Flow Coordinators
func makeMoviesSearchFlowCoordinator(navigationController: UINavigationController) -> MoviesSearchFlowCoordinator {
return MoviesSearchFlowCoordinator(navigationController: navigationController,
dependencies: self)
}
}
// Define makeMoviesListViewController closure that returns MoviesListViewController
class MoviesSearchFlowCoordinator {
private var makeMoviesListViewController: () -> MoviesListViewController
init(navigationController: UINavigationController,
makeMoviesListViewController: @escaping () -> MoviesListViewController) {
...
self.makeMoviesListViewController = makeMoviesListViewController
}
...
}
// And inject MoviesSceneDIContainer's `self`.makeMoviesListViewController function into class that needs it
final class MoviesSceneDIContainer {
...
// MARK: - Flow Coordinators
func makeMoviesSearchFlowCoordinator(navigationController: UINavigationController) -> MoviesSearchFlowCoordinator {
return MoviesSearchFlowCoordinator(navigationController: navigationController,
makeMoviesListViewController: self.makeMoviesListViewController)
}
// MARK: - Movies List
func makeMoviesListViewController() -> MoviesListViewController {
...
}
}