Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1. iOS Clean Architecture + MVVM 정리 #69

Closed
Youngminah opened this issue Oct 29, 2021 · 1 comment
Closed

1. iOS Clean Architecture + MVVM 정리 #69

Youngminah opened this issue Oct 29, 2021 · 1 comment

Comments

@Youngminah
Copy link
Owner

Youngminah commented Oct 29, 2021

image

엉클 아저씨가 소개한 Clean Architecture의 5가지 목적 ⭐️

  • 프레임워크 독립성

    • 아키텍쳐는 라이브러리 존재 여부에 의존하지 않아야 한다.
    • 프레임워크의 한정된 제약에 억지로 집어 넣지 않고, 도구로써 사용하는 개념이여야 한다.
  • 테스트 가능

    • 비지니스 규칙은 UI, 데이터베이스, 웹 서버, 기타 외부 요인 없이 테스트 가능하여야 한다.
  • UI 독립성

    • 시스템의 나머지 부분을 변경할 필요 없이 UI를 쉽게 변경할 수 있다.
    • 예를들면, 비즈니스 규칙 변경 없이 웹 UI는 콘솔 UI와 치환되는 것.
  • 데이터베이스 독립성

    • 오라클 또는 SQL Server를 몽고, 빅테이블, 카우치 DB 등으로 바꿀 수 있다.
    • 비즈니스 규칙은 데이터베이스에 얽매이지 않는다.
  • 외부 기능 독립성

    • 실제로 비즈니스 규칙은 외부 세계에 대해 아무것도 모른다.

의존 규칙

  • 대개, 원의 바깥쪽으로 향할수록 고수준의 소프트웨어가 된다.
  • 소스코드의 의존성을 안쪽을 향하게끔 설계
  • 안쪽의 원은 바깥쪽의 원을 모르는 상태
  • 안쪽의 원은 어떠한 것도 바깥 원에 어떠한 것도 참조 하고 있으면 안됨
    • (함수, 클래스, 변수 등 이름이 붙은 소프트웨어의 엔티티 모든 것)
  • 바깥쪽의 원은 메커니즘(Mechanism)이고 안쪽의 원은 정책(Policy)이다.

Entity

  • Entity (=Enterprise Business Rules): 사용자가 필요로 하는 데이터 모델을 의미
  • 특정 '도메인'에서 사용되는 struct모델
  • ex) Actor가 필요로하는 Movie와 MoviesPage에 관한 Entity
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?
}

struct MoviesPage: Equatable {
    let page: Int
    let totalPages: Int
    let movies: [Movie]
}

Use Case

  • Use case (= Application Business Rules)
  • 사용자가 Entity를 원하는데, 이 값은 계산되거나 특정 로직에 의해서 얻어지므로 Actor가 원하는 Entity를 얻어내고 있는 '로직'을 의미
  • ex) 사용자가 원하는 Entity인 MoviesPage를 얻기 위해서 필요한 '로직'
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)
        })
    }
}

struct SearchMoviesUseCaseRequestValue {
    let query: MovieQuery
    let page: Int
}

Presenter

  • Entity 데이터를 그대로 표현 ('present') 하는데 필요한 계층
    • Coordinator
    • View
    • ViewModel
    • Behaviors: 특정 View의 event에 관해 적용되는 UI

External Interfaces

  • 안쪽의 원과 통신할 연결 코드 이외에는 별다른 코드를 작성하지 않는 계층
  • 네트워크, DB 같은 것을 의미
    • Network(URLSession)
    • DB(CoreData, UserDefaults)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant