[iOS] CleanArchitecture 톺아보기

Hyunndy·2023년 3월 11일
0

🐸

CleanArchitecture 공부하면서 헷갈렸던 용어들과
각 layer들에 그래서 정확히 어떤게 들어가야 할지

Clean Architecture and MVVM on iOS 참고해서 정리했습니다.


개요

CleanArchitecture은 로머트 C 마틴이 고안한 아키텍처로,
소프트웨어를 다양한 계층(Layer) 로 분리해서 다음과 같은 목표를 추구합니다.

  • 아키텍처는 소프트웨어 라이브러리의 존재에 의존하지 않음
  • 비즈니스 로직은 UI, DB, 웹 서버 또는 기타 외부 요소 없이 테스트 할 수 있음
  • UI는 시스템을 변경하지 않고도 쉽게 변경 가능(ex. 비지니스 로직을 변경하지 않고 UI 변경 가능)
  • 비즈니스 로직이 DB에 바인딩 되지 않음
  • 비즈니스 로직은 outside world에 대해 전혀 알지 못함

소프트웨어에서 맡은 역할에 따라 레이어를 나눈 뒤, 완전 분리시켜서 의존성을 최대한 낮추는게 목적인 듯 합니다.

클린 아키텍처 다이어그램은 다음과 같습니다.

소프트웨어를 총 4개의 영역으로 나눴습니다.

👩‍💻
여기서 가장 중요한 개념은 내부 레이어는 외부 레이어를 절대! 몰라야 합니다.
(= 즉, 내부 레이어는 외부 레이어에 의존성(Dependency)를 가지면 안됩니다)

외부 Layer부터 차례대로 보겠습니다!


Data Layer

데이터 레이어는 다음 내용을 포함합니다.

  • Repository 구현체
  • 여러 DataSoruce

DataSource

데이터를 가져오는 곳을 말합니다.

  • API 객체
  • 로컬 DB (CoreData, KeyChain, plist 등)
  • 캐시

등이 있습니다.

Repository 구현체

여러 DataSource에서 데이터를 가져오고 저장하기 위한 객체 입니다.

  • API에서 받아온다면?
    - Alamofire, URlSession 등이 데이터를 가져오는 코드가 담겨있는 객체

  • 로컬 DB에서 데이터를 가져온다면?
    - 해당 DB와의 상호작용을 처리하는 코드를 구현
    (ex. DB 스키마 조회, 쿼리 작성, 트랜잭션 관리 등)

일반적으로
1) 데이터소스에서 받아온 데이터를 Entity로 매핑
2) Entity에 CRUD 작업(Create, Read, Update, Delete)을 수행하고, Domain Model 변형시킵니다.

👩‍💻
Repository 구현체는 보통 Repository Interface와 함께 구현되어 Interface를 통해 데이터를 가져오는 방법을 정의합니다.
Reposiotry Interface는 Domain Layer의 UseCase에서 Data Layer에서 데이터를 받아올 때 발생하는 (의존성 역전)을 해결하기 위해 정의된 인터페이스 입니다.
Data Layer에서 Repository 구현체를 구현하고 Domain Layer에서 Repository Interface를 가짐으로써 Data Layer가 변경되더라도 Domain Layer에 영향을 미치지 않도록 합니다.


UI Layer + Presenter Layer

View

ViewController, SwiftUI View, UIKit을 상속하는 모든 View Class를 말합니다.
Presenter(ViewModel)을 통해 Domain Layer에 간접적인 접근을 하는것이 권장 됩니다.

👩‍💻
ViewController, UICollectionViewCell 등 에서 Domain Layer(Use Case)를 직접 호출하지 말고 ViewModel을 통해 접근하라는 뜻입니다.

ViewModel

ViewModel 입니다.
UI Layer을 통해 유저의 입력을 받아 Use Case를 호출해 비즈니스 로직을 수행하는 계층 입니다.
보통 MVVM 패턴으로 구현되며, ViewModel에서는 되도록 UI 로직(UIkit을 임포트 한다던가..) 하지 않는 것이 좋습니다.


Domain Layer

살펴보기 전에 잠깐.. 도메인이란 무엇일까요?

👩‍💻 도메인이란

도메인이란 소프트웨어 시스템이 구축되는 대상 영역을 말합니다.
쇼핑몰 앱이라면, 쇼핑몰이라는 도메인에 대한 지식과 요구사항을 분석하여 시스템을 구축하게 됩니다.
즉, 도메인은 앱이 제공하는 기능과 서비스의 범위를 말합니다.

Domain Layer는 이러한 도메인 지식과 요구사항
(ex. 쇼핑몰이라는 개념 + 주문, 장바구니 등 유저의 니즈)
을 반영한 비즈니스 로직을 담당하는 계층 입니다.

🙅‍♀️ Domain Layer에서 절대 다른 Layer를 참조하지 않게 조심해야 합니다.

Entity (= Business Model)

여러 DataSource에서부터 가져온 데이터 그 자체를 말합니다.
일반적으로 Codable을 채택하고있는 그 객체 입니다.

Use Case

앱의 비즈니스 로직이 정의되어 있는 객체 입니다.

Presenter Layer에서 호출되어 사용되며,
좋은 아키텍처는 Use Case 중심으로 구현되어 있습니다.

Reposiotry Interface

Domain Layer에서 사용자의 요청을 처리하다보면, Data Layer에 의존성을 갖는 의존성 역전 현상이 발생하게 됩니다.

👩‍💻
예를들면, 사용자가 새로고침을하는 fetch 요청이 들어오면, Use Case는 Data Layer에게 다시 데이터를 요청하라고 해야합니다.

그래서 Repository Interface를 정의하고, 구현은 Data Layer에서 하게해서 의존성 역전 현상을 해소할 수 있습니다.

Domain Layer에 대해 더 알아보기 위해, Clean Architecture의 Data Flow를 보겠습니다.

Data Flow

Domian Layer는 애플리케이션의 핵심 로직을 담당하기 때문에 Presentation Layer, Data Layer 사이에서 중간 계층의 역할을 합니다.

👩‍💻
1) Presentaion Layer(View, ViewModel)에서 유저 요청을 받고
2) Data Layer(API, Network, DomainModel)에서 데이터를 받아오고 가공하고
3) Domain Layer(UseCase, Entity)에서 유저 요청 + 가져온 데이터를 조합하여
4) 사용자의 요청에 맞는 데이터를 Presentation Layer로 반환한다.

이를 통해 이 두 Layer 사이의 의존성을 낮추고, 유연성과 재사용성을 늘릴 수 있습니다.


Domain Layer의 비즈니스 로직(= 도메인 로직)에 대해

항상 개발하면서 비즈니스 로직이 뭔지 정확한 정의를 할 수가 없었습니다.
이번 Clean Architecture 정리를 하면서 뭔가 기준이 생겼는데,
도메인이 앱이 제공하는 서비스와 범위라고 했으니...
앱이 사용자에게 제공하는 기능 위주로 생각하면 되지 않을까 싶다.

사용자에게 제공하는 "기능"을 위한 코드는 비즈니스 로직,
그걸 받아서 UI에 뿌리는 코드는 UI 로직 이런식으로 말이다.
(물론 더 많은 에시가 있어야 겠지만)


마무리

핸드메이드로 CleanArchitecture 다이어그램까지 그리니 뭔가 명확해지는 기분이다.

profile
https://hyunndyblog.tistory.com/163 티스토리에서 이사 중

0개의 댓글