본내용은 https://github.com/android10/Android-CleanArchitecture 의 내용을 요약 정리 하였습니다.

"SHOULD NOT REINVENT THE WHEEL" 



Android Clean architecture principle



clean architecture란 다음과 같은 시스템을 생산하는 일련의 양식을 의미합니다.


  • Independent of Frameworks. 
  • Testable.
  • Independent of UI.
  • Independent of Database. 
  • Independent of any external agency. 


그림에 대한 설명 : 내부원의 경우에는 외부에 있는 원의 영역에 대해서는 생각할 필요가 없고 겹치는 영역도 존재하지 않는다. 

- Entities : 어플리케이션의 비지니스 오브젝트

- UseCases : 인터렉터라고 불리우며 엔티티간에 데이터흐름을 조정함

- Interface Adapters : 유즈케이스와 엔티티에 가장 편리한 형태로 데이터를 변환하는 역할을 한다. Presenter와 Controller가 여기에 속한다

- Frameworsk and Drivers : UI, Tools, fraemework 등을 포함




Android architecture


.친구 목록을 누르면 친구에 대한 상세 내용이 나오는 앱을 구성하는 시나리오로 Android architecture에 대해서 설명한다.

Android architecturing의 목적은  separation of concerns 이다. 비즈니스룰은 자신의 원 밖의 일에 대해서는 몰라도 된다. 따라서 비지니스룰은 외부적인 요인과는 

상관없이 테스트가 가능해야 한다.  이 목적을 이루기 위해서 프로젝트를  서로의 목적이 다르며 독립적으로 동작하는 3개의 다른 레이어로 구분했으면 한다. 


각각의 레이어는 독립성을 보장하기 위해서 독립된 데이터 모델을 가지고 있음을 언급할 필요가 있다. 



clean_architecture_android



Presentation Layer


이 레이어에서 뷰와 애니메이션과 관련된 동작들이 이루어 집니다.  MVC 나 MVVM 어떠한 패턴을 사용해도 상관은 없습니다. 그러나 fragments나 activity들은 view만 담당합니다.  UI로직을 제외하고는 어떠한 로직도 들어가서는 안되며 화면이 그려지는 모든 부분이 이곳에서 동작합니다.


이 레이어의 Interactors(유즈케이스)로 구성된 Presenters는  Android의 메인 UI thread의 밖에서 새로운 thread를 생성해서 동작하고 Callback 을 통해서 화면을 그려주게됩니다.  (https://github.com/pedrovgs/EffectiveAndroidUI/)


clean_architecture_mvp





Domain Layer


비즈니스 룰과 관련되 내용은 모두 이 레이어에서 일어나게 됩니다.  안드로이드프로젝트라면 모든 use case의 구현을 이 레이어에서 볼 수 있습니다.

이 레이어는 순수한 자바 모듈이고 안드로이드와 어떠한 디팬던시 없이 구현됩니다. 모든 비지니스 오브젝트와 외부 컴포넌트는 인터페이스로만 통신하게 됩니다. 



clean_architecture_domain




Data Layer


어플리케이션의 모든 데이터는 UserRepository구현체(Domain Layer 인터페이스)를 통해서만 가지고 올수 있으며, 팩토리를 통해 특정 조건에 따라 데이터소스를 선택하는 전략과 함께 레파지토리패턴을 사용한다. 

예를 들어 사용자 id 를 가지고 오는 경우 캐시에 사용자 id가 있으면 Disk 소스에서 가지고 오고, 그렇지 않으면 클라우드에서 조회한후 디스크 캐쉬에 저장하는 식으로 동작한다.

이때 클라이언트는 데이터가 어떻게 처리되는지(메모리에서 오든지, 클라우드에서오든지) 신경쓰지 않고 데이터를 가져다 쓰는 부분에만 집중하면 된다. 


clean_architecture_data





Error Handling


위에서는  콜백메소드를 사용했다. 데이터레파지토리의 경우에는 onResponse()와 onError() 같이 두가지 콜백 메소드를 사용했다. OnError() 는 ErrorBundle이라는 래퍼클래스를 캡슐화합니다. 이런방식은 렌터링할 프레젠테이션 레이어까지 콜백체인을 형성하기 때문에 여러가지 어려움이 생길수 있습니다. 또한 코드 가독성이 손상될 수 있습니다. 

반면에 무엇인가 잘못되면 이벤트를 던지는 이벤트 버스 시스템을 구현할 수 있습니다. 여러이벤트를 subscribe하는 가운데 세밀하게 다루지 않으면 에러를 놓치는 경우가 발생 할 수 있다.(?)



Testing


Testing과 관련하여서는 레이어 별로 다른 솔루션들을 선택했습니다.

.Presentation Layer : Android instrumentation 과 espresso를 통합 및 기능테스트를 위해서 사용했습니다.

.Domain Layer : 단위테스스트를 위해 JUnit 과 mockito를 사용했습니다.

.Data Layer : Android 와의 의존성때문에 Robolectric , Junit, mockito를 사용했습니다.





본 소스코드 : https://github.com/android10/Android-CleanArchitecture

  • presentation: 프레젠테이션 레이어를 구현한 안드로이드 모듈
  • domain: 안드로이드 디팬던시가 없는 자바 모듈
  • data: 모든 데이터 조회가 가능한 안드로이드모듈
  • data-test: 데이터 레이어를 위한 테스트 모듈.




Conculution


아키텍처가 모든 능사는 아니다. 그러나 위와 같은 방법을 사용한다면 다음과 같은 장점은 얻을수 있다.

  • 쉬운 유지보스
  • 쉬운 테스트
  • 높은 모듈 응집도
  • 낮은 결합성











+ Recent posts