예제로 Clean Architecture + MVVM 이해하기

toma·2022년 11월 14일
1
post-thumbnail

클린 아키텍쳐를 프로젝트에 적용해본 적은 있지만, 개념정도만 이해하고 예제를 보면서 적용하다보니 쓰면서 굉장히 헷갈렸던 기억이 있습니다..💦

그래서 이번에 진행하게된 프로젝트에서는 확실히 이해하고 적용해보고자 하나하나 뜯어보려고 합니다.

이 분은 클린 코드라는 책의 저자이자, 애자일 창시자 중 한명인 소프트웨어 엔지니어 로버트 C 마틴인데요.

이 분이 고안한 게 바로 그 유명한 클린 아키텍쳐입니다!

클린 아키텍쳐를 작동시키는 가장 우선적인 규칙은 Dependency Rule입니다.

Dependency Rule

바깥쪽부터 Frameworks & DriversInterface Adapters, UseCases, Entities 네가지 레이어로 이루어져있습니다.

다이어그램에서는 네가지이지만 레이어의 개수가 절대적인 것은 아닙니다.

outer circle에서 inner circle로만 의존하는 Dependenct Rule을 지키고,
안쪽으로 갈 수록 추상화 수준이 증가하면 됩니다.

Crossing Boundaries

앞서 살펴본 레이어를 보면
DB → Controllers(Presenters) → UseCases → Entities
이런 식으로 Dependency Rule을 가지고 있었죠?

하지만 UseCases가 Prseneters를 호출할 수도 있습니다.

🤬 아니 안된다매요!!! 안쪽으로만 의존해야하는데 어떻게 안쪽 레이어에서 바깥 레이어 호출함?

직접 Presenter를 호출하는 것이 아니라 UseCase에서는 인터페이스를 호출하고,
Presenter가 해당 인터페이스의 세부사항을 구현합니다.

결론적으로 안쪽에 있는 레이어인 UseCase가 바깥쪽 레이어에 있는 Presenter에 직접적으로 접근하는 것이 아니라

UseCase내에 인터페이스를 Prseneter가 구현하므로써 간접적으로 UseCase가 Presneter에 접근할 수 있게 되는 것입니다!

Movies App 예제

클린 아키텍쳐와 MVVM을 적용한 예제입니다.

예제는 영화 제목을 검색하면 겸색 결과 리스트가 나오고, 상세 뷰를 볼 수 있는 간단한 영화 검색 앱입니다! +캐시를 이용해서 검색어 저장해줌


Layers

예제에서는 UseCaseEntitiesDomain Layer라고 그루핑하여서
Presentation, Data, Domain Layer가 총 세가지 레이어가 존재하게 됩니다.


Domain이 원 가장 안쪽에 자리하게 되고,
PresentationData가 각각 Domain에 의존성을 가지게 됩니다.


폴더링과 매핑해보면, 전체적으로 이런 식의 구조로 되어있습니다!

이제 각자 레이어가 무슨 일을 하는지 자세히 알아보겠습니다!!

Domain layer(Business logic)

  • 그래프의 가장 안쪽 → 완전히 고립되어 있는 상태
  • 바깥을 아무것도 알 수 없다
  • Entity(Business Model), Use Case, Repository Interface 를 포함
  • 이 레이어는 다른 프로젝트에서도 재사용될 수 있다
  • 이렇게 레이어가 분리돼서 다른 의존성이나 3rd party가 필요하지 않기 때문에 앱을 테스트할 때 환경에 구애받지 않게 하고, 따라서 도메인 Use case 테스트를 몇 초 내에 할 수 있다

도메인 레이어의 핵심은 다른 레이어(Presentation의 UIKit/SwiftUI나 Data 레이어의 Mapping Codable)의 어떤 것도 포함시키면 안되는 것이라고 하네요.

Presentation layer

  • UI(UIViewController / SwiftUI View)를 포함
  • 각 View는 하나 이상의 Use Case를 실행시키는 ViewModel(Presenters)와 대응된다
  • 즉 한 view에 대응되는 하나의 viewModel이 있다.
  • 도메인 레이어에만 의존한다.

Data layer

  • Repository 구현체, 그리고 하나 이상의 Data Source를 포함
  • Repository Interface는 도메인 레이어에 속함
  • Data Source는 원격이나 로컬일 수 있음
  • 오로지 도메인 레이어에만 의존
  • 네트워크로 받은 JSON 데이터를 도메인 모델로 매핑하는 것을 포함시킬 수 있다.

예제 프로젝트에서도 Data layer의 DefaultMoviesRepository에서 API로 받은 결과를 domain 모델로 매핑하거나, 리퀘스트를 dto로 매핑해줍니다!

데이터 흐름

  1. View(UI)가 ViewModel(Presenter)로부터 메서드를 호출
  2. ViewModel은 Use Case를 실행
  3. Use Case는 유저와 레포지토리로부터 데이터를 결합
  4. 각 레포지토리는 리모트 데이터(네트워크)와 Persistent DB, In-memory 데이터로부터 온 데이터를 반환
  5. 정보가 View(UI)로 다시 흘러가고 이를 화면에 띄움

예제 프로젝트에서는클린 아키텍쳐와 MVVM 뿐만 아니라,
코디네이터와 DI컨테이너라는 것도 적용했는데요,,,,, ◠‿◠

코디네이터는 제가 저번에 포스팅했던 주제로 델리게이트 패턴을 통해 화면을 전환하는 패턴입니다. 그리고 DI컨테이너는 코디네이터 패턴과 비슷한데 의존성 주입을 담당하는 컨테이너라고 생각하면 될 것 같습니다..

기회가 된다면 해당 프로젝트에 적용된 DI컨테이너와 actions, behavior도 추가적으로 뜯어보는 시간을 ...... 가져보고 싶네요..

저의 머리로 이해하기에는 진짜 구조가 🐶복잡해서 한번 흐름을 그림으로 표현해보았습니다..

조금이라도 도움이 되기를 바라며...

참고

[iOS] - Clean Architecture, 직접 해보기

Clean Architecture

profile
Don't think, just do 🎸

0개의 댓글