본문 바로가기
안드로이드/Android

[Android] Clean Architecture

by jinwo_o 2025. 1. 22.
  • 소프트웨어 개발은 복잡한 문제를 해결하기 위해 코드를 작성하는 것 이상을 필요하다. 단순히 결과론으로 화면을 보여주는 것만 생각하고 개발한다면, 코드는 점차 커지며 나중에는 손볼 수 없을 정도로 난폭한(?) 코드로 변하게 된다.
  • 그렇기에 개발한다는 것은 유지보수성, 확장성, 테스트 용이성 등의 요구 사항을 충족하기 위한 고민이 필요하며, 적절한 아키텍처 설계가 필수이다.

 

Android Clean Architecture

  • Presentation(UI) Layer, Domain Layer, Data Layer 총 3가지 레이어로 구성되어 있다.
  • 각 레이어들은 *단방향 데이터 흐름으로 통신한다.
    • 단방향 데이터 흐름 : 데이터가 오로지 한 방향으로만 흐르는 것으로 *Up Stream 과 *Down Stream 방식으로 구성되어 있다.
      • Up Stream : 사용자가 클릭 등의 이벤트를 발생시키면, UI → Domain → Data 레이어로 전달함으로써 상위 레이어로 전달하는 방식
      • Down Stream : Remote or Local Server 로부터 받은 데이터를 Data → Domain → UI 레이어로 전달함으로써 하위 레이어로 전달하는 방식
  • 시스템의 각 부분을 독립적으로 개발하고 테스트할 수 있는 환경을 조성할 수 있다.
  • 시스템의 변경이나 업그레이드가 필요할 때 전체 시스템을 다시 작성하지 않아도 되며, 특정 부분만 수정하는 것이 가능하다.
  • 유지보수 용이성 : 각 계층이 분리되어 있기 때문에 한 계층을 변경해도 다른 계층에 영향을 미치지 않아 유지보수가 쉽다.
    • 의존성 관리 및 모듈화를 통해 애플리케이션의 유지 보수성이 MVVM 보다 향상된다.
      • MVVM 은 뷰와 뷰 모델 간의 관계에 중점을 두는 반면 Clean Architecture 는 시스템의 전반적인 구조를 고려한다.
  • 테스트 용이성 : 의존성을 주입하여 유닛 테스트 및 통합 테스트를 수행하기 용이하다.
    • 유지 보수성 향상과 동일 이유로 각 계층이 독립적으로 테스트 가능하도록 설계되어 있어 테스트 용이성을 높일 수 있다.
    • 유닛 테스트, 통합 테스트 등을 보다 쉽게 테스트를 진행할 수 있다.
  • 모듈 간의 분리 : 각 계층이 자체 역할을 가지며, 이로 인해 코드의 재사용성이 높아진다.
    • 새로운 기능을 추가하거나 기존 기능을 변경하려는 경우, 변경의 범위를 최소화하며 애플리케이션을 확장하기 유용하다.
  • 데이터베이스나 UI 프레임워크 변경 용이성 : 중요한 비즈니스 로직은 외부 프레임워크와 분리되어 있어 해당 프레임워크를 변경하더라도 기존에 작성한 전체 코드를 다시 작성할 필요가 없다.
    • MVVM 도 비즈니스 로직을 ViewModel 에서 처리하여 독립적으로 운영할 수 있다. 하지만 프로젝트가 커짐에 따라 비즈니스 로직을 ViewModel 에서 관리하기에는 어려울 수 있다.

 

주요 원칙

  • 의존성 역전 원칙(DIP) : 고수준 모듈은 저수준 모듈에 의존해서는 안되며, 양쪽 모듈 모두 추상화에 의존해야 한다. 이를 통해 느슨한 결합을 유지할 수 있다.
  • 경계의 분리 : 시스템을 여러 영역으로 나누고, 각 영역 사이의 인터페이스를 정의하여 각 영역의 독립성을 보장한다.
    • 경계는 소프트웨어 요소를 서로 분리하고, 경계 한편에 있는 요소가 반대편에 있는 요소를 알지 못하도록 막는다.
    • 화살표의 방향은 의존성을 뜻한다. 클린 아키텍처의 의존성은 밖에서 안으로 향하고, 바깥 원은 안쪽 원에 영향을 미치지 않는다.
    • 경계의 바깥으로 갈수록 덜 중요하고 세부적인 영역으로 표현되며, 안으로 갈수록 고수준(좀더 추상회된 개념)으로 표현된다.
  • 인터페이스 분리 원칙 : 클라이언트가 자신이 사용하지 않는 메서드에 의존하지 않아야 한다. 즉, 인터페이스는 클라이언트의 요구에 딱 맞는 형태로 분리되어야 한다.
 

[Kotlin] 객체 지향 원칙(SRP, OCP, LSP, ISP, DIP)

객체지향 설계에서 지켜줘야 할 5개의 소프트웨어 개발 원칙(SRP, OCP, LSP, ISP, DIP)SOLID 객체 지향 원칙을 적용하면 코드를 확장하고 유지 보수 관리하기가 더 쉬워지며, 불필요한 복잡성

dev-baik.tistory.com

 

Presentation Layer

  • 사용자 인터페이스(UI)와 비즈니스 로직 간의 중간 계층으로, UI 에서 발생한 이벤트를 처리하고 필요한 데이터를 비즈니스 로직에 전달한다.
  • 화면과 입력에 대한 처리 등 UI 와 관련된 부분을 담당한다.
  • Domain 계층에 대한 의존성을 가지고 있다.

 

  • 뷰(View) : 직접적으로 플랫폼 의존적인 구현, 즉 UI 화면 표시와 사용자 입력을 담당한다. 단순하게 프레젠터가 명령하는 일만 수행한다.
  • 프레젠터(Presenter) : MVVM 의 ViewModel 과 같이, 사용자 입력이 왔을 때 어떤 반응을 해야 하는지에 대한 판단을 하는 영역이다. 무엇을 그려야 할지도 알고 있는 영역이다.
    • UpStream 관점에서 ViewModel 은 '비즈니스 로직의 출발 지점'으로, Domain 레이어나 Data 레이어에 이벤트를 전달하며 비즈니스 로직의 시작을 트리거하게 된다.
    • DownStream 관점에서 ViewModel 은 Domain 레이어나 Data 레이어로부터 UI 에 바인딩될 데이터 구조를 응답 받는다. 그리고 전달받은 응답을 통해 UI 에 데이터 바인딩을 진행한다.

 

Domain Layer

  • Presentation, Data 계층에 대한 의존성을 가지지 않고 독립적으로 분리되어 있다.
  • 안드로이드의 의존성을 갖지 않고 java 및 kotlin 코드로만 구성하며 다른 애플리케이션에서도 사용할 수 있다
    • 아이폰이나 웹 전용으로도 개발해야 하는 경우, 내부 동작이 거의 동일하므로 순수 Kotlin 으로 공통 로직을 모듈로 분리하여 설계하면 여러 플랫폼에서 활용할 수 있다.
    • 비즈니스 로직을 아이폰과 웹 개발자들이 각각 구현하더라도, 다른 플랫폼 개발자는 Domain 모듈만 보고 이 서비스의 비즈니스 로직을 빠르게 파악하고 개발할 수 있다.

 

  • 유스케이스(UseCase) : 애플리케이션의 실제 비즈니스 로직을 포함하는 부분으로, 프레젠터나 뷰모델로부터 전달된 요청을 처리하고 데이터를 가공하여 반환한다.
    • 애플리케이션의 특화된 업무 규칙을 포함한다.
    • 시스템의 모든 유즈케이스를 캡슐화하고 구현한다.
    • 엔티티로 들어오고 나가는 데이터 흐름을 조정하고 조작한다.
    • 네이밍 규칙 : 현재 시제의 동사 + 명사/대상(선택사항) + UseCase
    • ViewModel 에서 UseCase 를 파라미터로 전달 받아서 사용하게 된다. ViewModel 이 어떤 것을 하고자 하는지 직관적으로 파악할 수 있다.
    • UseCase 를 사용하지 않으면 ViewModel 에서는 Repository 를 전달 받아서 사용하게 되는데, 전달 받은 Repository 가 수정이 된다면, Repository 를 사용하는 많은 부분에서 수정이 이루어져야 할 가능성이 높다.
      • 하지만, UseCase 를 사용하게 되면 영향이 있는 UseCase 를 사용하는 부분에서만 수정을 하면 되기 때문에 의존성이 줄어든다.
  • 엔티티(Entity, 모델) : 앱의 실질적인 데이터
    • 핵심 업무 규칙을 캡슐화한다.
    • 메서드를 가지는 객체, 일련의 데이터 구조와 함수의 집합이다.
    • 가장 변하지 않으며 외부로부터 영향을 받지 않는 영역이다.

 

Data Layer

  • Domain 계층에 대한 의존성을 가지고 있다.
  • Domain 계층의 Repository 구현체, 데이터베이스, 서버와의 통신을 포함하고 있다.
  • mapper 클래스를 통해 Data 계층의 모델을 Domain 계층의 모델로 변환해주는 역할을 한다.

 

  • 레포지토리(Repository) : 데이터베이스나 외부 데이터 원본과의 상호 작용을 담당하는 부분으로, 데이터를 가져오고 저장하는 작업을 수행한다. 유스케이스는 리포지토리를 통해 데이터를 얻어온다.
    • 유즈 케이스가 필요로 하는 데이터의 저장 및 수정 등의 기능을 제공하는 영역으로, 데이터 소스를 인터페이스로 참조하여, 로컬 DB 와 네트워크 통신을 자유롭게 할 수 있다.
    • UpStream 관점에서 앱 내에서 필요한 데이터를 DataSource 에 요청하는 역할을 맡고 있다.
    • DownStream 관점에서 DatsSource 에서 받아온 데이터를 새로운 모델로 가공하여 하위 레이어(Domain 또는 UI)에 전달하는 역할을 맡고 있다.
    • 데이터의 출처에 관계 없이 동일한 인터페이스로 데이터 접근할 수 있도록 한다. ViewModel 에서 직접 데이터에 접근하여 데이터를 가져오는 것이 아니라, ViewModel 에서는 Repository 만 접근을 하게 된다.
      • 즉, Data Layer 가 캡슐화가 되고, ViewModel 이 포함되어 있는 Presentation Layer 에서 Data Layer 를 직접 호출하지 않고 Repository 를 통해서만 접근이 가능하게 되는 것이다.
        • Data Layer 에 대한 의존성을 줄일 수 있다. 즉, Presentation Layer 와 Data Layer 간의 결합도가 줄어든다.
        • Presentation Layer 에서 Data Layer 에 직접 접근하지 않으므로, 새로운 데이터의 추가가 쉽다.
        • Presentation Layer 에서는 Repository 에 데이터 요청만 하면 되므로, 일관된 인터페이스로 데이터를 요청할 수 있다.
        • Unit Test 를 통한 검증하기가 쉬워진다.
  • 데이터 소스(Data Source) : 실제 데이터의 입출력이 실행되는 영역
    • UpStream 관점에서 Repository 가 필요한 데이터를 Remote or Local Server 에 요청한다.
    • DownStream 관점에서 Repository 에 데이터를 제공한다.
  • 엔티티(Entity, 모델) : 네트워크나 로컬 DB 에서 받아온 DTO

 

왜 Android 신규 프로젝트는 클린 아키텍처를 도입하였는가

소프트웨어 개발은 복잡한 문제를 해결하기 위해 코드를 작성하는 것 이상을 필요로 합니다. 단순히 결과론으로 화면을 보여주는 것만 생각하고 개발한다면, 코드는 점차 커지며 나중에는 손볼

medium.com

 

[Android] 요즘 핫한 Clean Architecture 왜 쓰는 거야? : NHN Cloud Meetup

[Android] 요즘 핫한 Clean Architecture 왜 쓰는 거야?

meetup.nhncloud.com

 

안드로이드 Clean Architecture에 대하여

0. 시작하며 >안드로이드 클린 아키텍쳐에 대하여 객관적으로 알려드리기 위해, [안드로이드 공식 홈페이지의 권장 아키텍쳐]를 토대로 말씀드리고 있음을 밝히며 글을 시작해볼까 해요. 사실

velog.io

 

[Android] Clean Architecture in Android

Clean Architecture란? 고객들에게 제공하는 애플리케이션 같은 경우에는 수많은 기능들이 있기에 복잡도가 굉장히 높습니다. 복잡도가 높은 애플리케이션을 개발할 때 어떻게 하면 유지 보수하기

leveloper.tistory.com

 

[Android] Clean Architecture - UseCase 란 ?

처음 학습하면서 작성한 글입니다. 필요시 추후 내용을 수정할 예정입니다. 틀린 부분이 있으면 언제든 지적해주면 감사하겠습니다 :) Clean Architecture 를 공부하는 도중에, UseCase 라는 것을 domain l

heegs.tistory.com

 

[Android] Repository Pattern

디자인 패턴을 살펴보던 도중, Repository Pattern을 적용해본적은 있지만 정리를 하지 않았던 것을 발견하여 간단하게 정리를 하면서 글을 작성해보고자 한다. Clean Architecture 예제를 확인해보면 repos

heegs.tistory.com

'안드로이드 > Android' 카테고리의 다른 글

[Android] MVI  (0) 2025.01.26
[Android] LiveData, Flow  (0) 2024.12.22
[Android] 프로그램(Program), 프로세스(Process), 스레드(Thread)  (0) 2024.12.11