본문 바로가기

iOS

[iOS] CleanArchitecture & Tuist를 활용한 리팩토링 후기(?)

Tuist & CleanArchitecutre 도입기

안녕하세요!

 

이번 포스트는 기존 프로젝트 리팩토링을 진행하며 MVVM 구조에서 CleanArchitecture & Tuist와 ReactorKit 도입을 진행한 경험을 공유하는 포스트입니다 :D

 

이전에 진행하다 잠시 펜딩되었던 프로젝트를 다시 진행하게 되었으며 이왕 다시 하는거 리팩토링을 해보자! 라는 생각에 리팩토링을 진행하게 되었습니다.

 

 

기존 구조


 

기존에는 모놀리식한 프로젝트 구조에서 MVVM-C 패턴으로 작업이 진행되었습니다.

 

MVC에서 Massive한 ViewController 현상을 피하기 위해 MVVM 패턴을 기반으로 작업을 진행하였으며

 

그 결과 ViewController 내 존재하던 비즈니스 로직은 ViewModel의 책임으로 이전할 수 있었으나 ViewModel은 아래와 같이 너무나도 많은 책임을 짊어지고 있었습니다.

 

  • API Call
  • 데이터 가공
  • ViewController에게 전달.
  • 화면 전환을 위한 Coordinator Call

 

간단한 기능을 수행하는 ViewController의 경우에는 ViewModel의 코드 또한 매우 간단했습니다.

 

그러나 다양한 기능을 수행하는 ViewController의 경우 ViewModel의 코드의 양이 꽤나 방대해졌으며 상황에 따라서는 ViewModel이 가지는 상태값을 트랙킹 하기 위해 Output Sequence를 다양한 Operator를 통해 여러 형태로 가공하여 사용하게 되었습니다.

 

특히 상태값에 대한 트랙킹을 위해 가공하는 형태에서 코드의 가독성에 대한 아쉬움을 많이 느끼고 있었으며 등등의 다양한 아쉬운 점을 리팩토링을 통해 해결해보고자 계획하게 되었습니다.

 

 

리뉴얼 계획


 

리뉴얼을 계획하며 어떤 점들을 고쳐나가면 좋을지 많은 고민이 있었습니다.

 

기존에 느꼈던 아쉬운 점을 보완할 수 있는 방식이 무엇이 있을지, 혹은 더욱 좋은 구조가 있을지, 다른 사람들은 어떻게 작성했는지 여러 프로젝트들을 살펴보고 고민한 결과 아래와 같이 스킬들을 결정했습니다.

 

 

  • Clean Architecture 도입: 기존에 겪던 Massive ViewModel이 가지던 책임들을 UseCase, Repository 패턴등을 통해 관심사를 분리하며 의존성을 역전 시켜 Testable한 코드 작성에 용이할 것 같다는 생각에 도입을 결정하였습니다.
  • Tuist 도입: Clean Architecture를 통해 프로젝트를 계층화 할 때, 해당 계층들을 모듈화하여 관리하는 것이 좋겠다는 생각에 도입을 결정하였습니다.
  • ReactorKit 도입: 기존에 다양한 Rx Operator를 통해 Sequecne들을 가공하여 사용하던 방식 대신 ViewModel의 상태값을 유지하며 이에 따라 반응하는 형태로 구현하고자 도입을 결정하였습니다.

 

리뉴얼은 현재 진행중


 

현재는 정해진 스택을 적용하여 리뉴얼을 진행중에 있습니다.

 

Tuist를 통해 아래 열거형과 같이 프로젝트를 계층 기반으로 모듈화하여 구현하고 있습니다.

 

enum Layer: CaseIterable {
  case core
  case domain
  case data
  case presentation
}

image

 

그 결과 이렇게 잘 정리된 모듈별 의존성을 가진 형태의 프로젝트 구조에서 작업이 가능했습니다!

 

또한 거대한 ViewModel 현상을 피하기 위해 아래와 같이 비즈니스 로직과 네트워킹 로직 처리시 UseCase, Repository를 활용하였습니다.

 

 

image

 

 

image

 

이렇게 정의한 Repository를 UseCase에서, UseCase를 ViewModel(Reactor) 에서 활용하였습니다.

 

기존에 너무나도 많은 일을 하던 ViewModel을 대신하여 지금의 ViewModel(Reactor)은 단순히 로직 처리를 요청하고 그 결과를 받아 상태를 관리하는 일만 수행합니다.

 

image

 

그 결과 CleanArchitecture를 통해 각 모듈들의 역할을 분명하게 분리할 수 있었고,

 

ReactorKit을 통해 ViewModel의 상태를 관리하며 이를 기반으로 View에 적용하는 것 까지 물 흐르듯 시퀀스의 흐름을 보다 보기 좋게 만들어 낼 수 있었습니다.

 

이렇게 보면 매우 간단해보이지만, 계층(Domain, Data, Presentation) 간 통신시 모두 인터페이스를 기반으로 로직을 작성하였으며 뷰에서 레포지터리까지의 로직을 작성하기 위해서 많게는 6개의 파일을 생성하거나 수정을 하게 되었습니다.

 

구현중에 이러한 번거로움이 느껴졌지만 코드에 대한 수정이 필요할 때 정말 사소한 수정으로 해결이 가능하다는 장점이 있었습니다.

 

새로운 화면과 기능들이 추가되더라도 유지보수와 확장의 용이성을 위해서는 위 번거로움을 감수하고 미래를 위해 투자(?) 라고 생각하며 작업하고 있습니다.

 

 

마무리


이번 리뉴얼을 계획 및 진행하며 Github에서 정말 다양한 코드들을 살펴보며 많은 고민이 있었습니다.

 

덕택에 더욱 많은 정보를 학습하였고 결론적으로 만족스러운 형태로 재탄생 시킬 수 있었던 것 같습니다!

 

앞으로도 열심히 구현할테니 코드가 궁금하신 분이 계시다면 아래를 방문해주세요~

 

Tidify Repository

'iOS' 카테고리의 다른 글

[iOS] RunLoop  (0) 2023.05.20
[iOS] Actor, Task, Async&Await  (0) 2023.04.02
[iOS] Static 그리고 Dynamic Dispatch  (0) 2022.06.24
[iOS] CleanArchitecutre 톺아보기 3 - Data  (0) 2022.06.23
[iOS] CleanArchitecture 톺아보기 2 - Domain  (0) 2022.06.22