[Android A..Z] Clean Architecture

2021. 11. 21. 21:41개발/[Kotlin] 안드로이드 개발

반응형

Clean Architecture란?

고객들에게 제공하는 어플리케이션 같은 경우에는 수많은 기능들이 있기에 복잡도가 굉장히 높다. 복잡도가 높은 어플리케이션을 개발할 때 어떻게 하면 유지 보수 하기 쉽고 고품질의 코드를 작성할 수 있을까? 어플리케이션은 새로운 기능이 추가된다거나 내부 로직이 변경되어야 하는일이 생겼을 때 유연하게 대처할 수 있도록 구조화 해야한다.

 

클린 아키텍처의 개념은 2012년에 Uncle Bob님이 블로그에 기재하며 세상에 나오게 되었다. 클린 아키텍처의 목표는 계층을 분리하여 관심사를 분리하는 것이다. 이게 무슨 의미가 있을까? 

 

예를 들어 안드로이드 로컬 DB를 기존에 Realm을 사용하고 있다. Realm으로 수많은 기능을 구현하고 이미 제품까지 나와 있는 상황이다. 그런데 갑자기 로컬 DB Realm을 Room DB로 교체해야 한다고 한다. 이미 프로젝트 복잡도가 높아져서 Realm에서 Room으로 바꾸기엔 쉽지 않다. Realm 인스턴스를 전부 Room인스턴스로 변경한 뒤, 그에 맞게 또 대처를 해줘야 한다. 클린 아키텍처로 프로젝트 구조를 잡는다면 변화에 유연하게 코드를 작성할 수 있다. 

Clean Architecture의 다이어그램

클린 아키텍처는 총 4가지의 계층으로 이루어져 있다. 클린 아키텍처의 각 계층에 대해 설명은 다음과 같다.

1. Entity

엔티티는 비즈니스 규칙을 캡슐화 한다. 엔티티는 메서드를 갖는 객체일 수도 있지만 데이터 구조와 함수의 집합일 수도 있다. 가장 일반적이면서 고수준의 규칙을 캡슐화하게 된다. 외부가 변경되더라도 이러한 규칙이 변경될 가능성이 적다.

2. Use cases

유스케이스는 어플리케이션의 고유 규칙을 캡슐화하며 엔티티로부터의 데이터 흐름을 조합한다. 유스케이스 계층이 변경이 엔티티에 영향을 줘서는 안되며 데이터베이스, 공통 프레임워크 및 UI에 대한 변경으로부터 격리된다.

3. Interface Adapters(Presenters)

인터페이스 어댑터는 Entity 및 UseCase의 편리한 형식에서 데이터베이스 및 웹에 적용할 수 있는 형식으로 변환한다. 이 계층에는 MVP 패턴의 Presenter, MVVM패턴의 ViewModel이 포함된다. 즉, 순수한 비즈니스 로직만을 담당하는 역할을 한다.

4. Frameworks & Drivers(Web,DB)

프레임워크와 드라이버는 상세한 정보들을 두게 된다. 웹 프레임워크 ,데이터베이스 ,UI, HTTP Client등으로 구성된 가장 바깥쪽 계층이다.

 

클린 아키텍처가 동작하기 위해서는 의존성 규칙을 잘 지켜야한다. 다시 말해 각각의 클래스는 한 가지 역할만 수행하고, 서로 의존 관계를 어떻게 할지 규칙이 정해져 있고 이를 지켜줘야 한다.

 

의존성 규칙은 반드시 외부에서 내부로, 저수준 정책에서 고수준 정책으로 향해야 한다. 위그림에서는 내부로 갈수록 의존성이 낮아진다. 예를 들면 안드로이드 ViewModel은 로컬 DB나 Web과 같은 세부적인 사항에 의존하지 않아야 한다. 이를 통해 비즈니스 로직(고수준 정책)은 세부 사항(저수준 정책)의 변경에 영향받지 않도록 할 수 있다.

 

이렇게 관심사를 나누면 다음과 같은 이점을 얻을 수 있다.

1. 새로운 기능을 빠르게 적용 가능

2. 집중화된 클래스에 따른 프로젝트 유지 관리에 용이하다.

3. 패키지 구조 탐색이 쉬워진다.

4. 테스트 코드 작성에 용이하다.

 

Clean Architecture in Android

 클린 아키텍처를 안드로이드에 접목시킬 때는 일반적으로 Presentation, Domain, Date 총 3개의 계층으로 나눠지게 된다. Presentation -> Domain, Data -> Domain 방향으로 의존성을 갖고 있다. 

1. Presentation

화면과 입력에 대한 처리 등 UI와 관련된 부분을 담당한다. Activity, Fragment,View,Presenter 및 ViewModel을 포함한다. Prsentation 계층은 Domain 계층에 대한 의존성을 가지고 있다.

2. Domain

어플리케이션의 비즈니스 로직에서 필요한 UseCase와 Model을 포함하고 있다. UseCase는 각 개별 기능 또는 비즈니스 논리 단위이며, Presentation, Data계층에 대한 의존성을 가지지 않고 독립적으로 분리되어 있다. 안드로이드의 의존성을 갖지 않고 Java 및 Kotlin 코드로만 구성하며 다른 어플리케이션에서도 사용할 수 있따. Repository 인터페이스도 포함되어 있다.

3. Data

Domain 계층에 의존성을 가지고 있다. Domain 계층의 repository 구현체를 포함하고 있고 데이터베이스, 서버와의 통신도 Data계층에서 이루어진다. 또한 Mapper 클래스를 통해 Data 계층의 모델을 domain계층의 모델로 변환해주는 역할도 한다.

 

위에서 Realm에서 Room으로 데이터베이스를 변경할 때 클린 아키텍처를 사용하면 변경이 용이하다고했다. Domain 계층에서 Repository 인터페이스를 작성하고 Data 계층에서 이를 구현한다. 데이터베이스는 Data 계층에서만 존재하기 때문에 Realm에서 Room으로 데이터베이스를 변경한다고 하면 Data 계층의 Repository 구현체만 Room으로 변경해주면 된다.

 Presentation 계층과 Domain 계층은 데이터베이스를 어떤 것을 사용하는지 전혀 알지 못한다. 때문에 Data 계층만 변경해주면 보다 쉽게 데이터베이스를 변경할 수 있다.

 

출처 : https://leveloper.tistory.com/205

반응형