그냥 가끔의 기록장

Android Clean Architecture 본문

Android

Android Clean Architecture

the phoenix 2021. 6. 8. 23:25

mvvm 하나 알겠다고 무작정 검색하던 것이 어느새 흘러흘러 clean Architecture로 갔다. 사실 아직도 안드로이드가 너무 어렵고 아는 내용이 많지 않아서 할 게 산더미같지만.. 아무튼 mvvm을 정복하기까지 mvp, mvvm, model, clean Architecture, data binding, live data, .... 찾아볼게 정말 많다. 매일 하나씩이라도 해나가야지. 

 

오늘은 우선 clean Architecture를 알아보고자 한다. https://proandroiddev.com/clean-architecture-data-flow-dependency-rule-615ffdd79e29 에 데이터 흐름과 종속성 규칙이 정말 정말 잘 나와있다. 

 

1. 데이터 흐름

 데이터 흐름은 그림과 같이 UI -> Presenter -> Use Case -> Entity -> Repository -> Data source 순으로, 그리고 이 순서의 역순으로 흐른다. 

출처: https://proandroiddev.com/clean-architecture-data-flow-dependency-rule-615ffdd79e29 

  즉, 사용자가 게시물을 작성하여 목록이 업데이트 되어야 하는 상황은 다음 순서로 이루어진다.

(1) UI 가 Presenter / ViewModel 에서 메소드를 호출

(2) Presenter / ViewModel 은 Use Case 실행

(3) Use Case는 사용자로부터 입력된 게시물과 목록 repository 데이터를 결합한다.

(4) 각 repository는 (cached or Remote) Data source로부터 데이터를 반환한다. 

(5) 역순으로 업데이트 된 게시물 목록이 UI에 보여진다. 

2. 종속성 규칙 

(1) Presentation Layer

- UI + 1개 이상의 Use Case 를 실행시키는 Presenter / ViewModel로 구성됨

- Domain Layer에 종속됨

 

(2) Domain Layer

- Entity + Use Case (1개 이상의 Repository Interface를 데이터와 결합시킴) + Repository Interface로 구성됨

- 다른  Layer와의 종속성 없음

 

(3) Data Layer

- Repository + 1개 이상의 Data source로 구성됨

- Domain Layer에 종속됨 

 

(음.. 뭔가 대충 사용자랑 상호작용 하는 UI 에서 Presenter / ViewModel로, Presenter / ViewModel에서 다시 data layer에 해당하는 repository+data source로 데이터가 이동한다는 것 같다. 그니까 종속성 규칙과 헷갈리면 안되는게, 종속성 규칙은 밖에서 안으로만 의존성을 가져야한다. 따라서 entity는 자신 외엔 아무것도 알지 못하나 Presentation layer에 해당하는 Presenter와 Data layer에 해당하는 Repository는 entity를 알고 있어야 한다.

의존성: UI ---> Presenter ---> Use Case ---> entity <--- Repository <--- Data Source

데이터 흐름:  UI ---> Presenter ---> Use Case ---> entity ---> Repository ---> Data Source 이런 느낌....)

 

여기서 내가 만난 문제는, 그래 의존성과 데이터 흐름은 대략 이해를 했는데 정작 그 내부에 있는 Presenter, Use Case, Entity, Repository, Data Source가 뭔지 정확히 모른다는 것이다.... 따라서 아래서 정리해보았다. 

 

3. Presenter / ViewModel

MVVM, MVP에서 말로만 듣던 그것들...사실 이게 제일 어렵고 아직 이해를 못한 듯 하다.. 

ViewModel은 MVVM 관점과 Android Jetpack 관점 두 가지로 나뉜다고 한다. 후자를 AAC ViewModel이라고 부른다. 

 

(MVVM 관점)

ViewModel은 우선 UI와 비즈니스 로직을 분리하려고 사용하는 것이다. ViewModel로 UI와 관련된 데이터를 분리시키면, 액티비티나 프래그먼트는 UI 업데이트에만 쓰이고 ViewModel의 데이터는 액티비티나 프래그먼트의 생명주기로부터 자유로워진다. 

즉, UI 로직과 비즈니스 로직을 분리해서 ViewModel의 데이터가 생명주기로부터 자유로워지니까! 쓰는 것으로 이해했다.

 

MVVM 관점의 ViewModel을 구현할 때 AAC ViewModel을 사용하면 좋다고 한다. 

 

자세한 내용은 아직 이해를 못한 관계로 다음 글 참고....! (참고: https://charlezz.medium.com/viewmodel%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80-viewmodel-%EC%B4%88%EB%B3%B4%EB%A5%BC-%EC%9C%84%ED%95%9C-%EA%B0%80%EC%9D%B4%EB%93%9C-e1be5dc1ac18 )

4. Use Case

1개 이상의 Repository를 받아서 비즈니스 로직을 처리하는 부분이다. Use Case 1개는 최소 행위 1개를 수행해야 한다고 한다. 즉, 어떤 정보 가져오기, 보여주기 이런 행위를 Use Case에서 처리하는 것이다. Use Case를 사용해야 하는 이유는 https://velog.io/@cchloe2311/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-UseCase%EB%A5%BC-%EC%99%9C-%EC%93%B0%EB%82%98%EC%9A%94 에 잘 나와있다.

 

요약하자면, Use Case를 사용하지 않으면 ViewModel이 모든걸 알고 있어야 하므로 모든 것에 의존성을 갖게된다. 반면, Use Case를 사용할 경우 ViewModel 에서는 Repository를 알 필요가 없으니 의존도가 낮아진다. (음...즉 CRUD나 network 통신 처리 등등 여러가지 행위들을 각각 캡슐화해서 Use Case를 만든다는 얘기로 이해했다. 이렇게 하면 코드 구현을 세부적으로 분리할 수 있으니까) 

5. Entity

Domain Layer의 Model (Data class)이 곧 Clean Architecture에서의 Entity라고 한다. Domain Layer는 다른 계층과 의존성이 있으면 안된다. 따라서 Data Layer 에서 Domain Layer로 데이터를 넘겨줄때는 직접 넘기는 것이 아니라 mapping 함수를 이용해 넘겨주어야 한다. 이 경우 Data layer가 바뀌어도 mapping만 바꿔주면 되니까 Domain Layer를 바꿀 필요가 없다. (출처: https://black-jin0427.tistory.com/225

 

원래는 이번 글에서는 이론만 설명하고 예제를 다른 글에서 하려 했는데, Entity는 예시를 드는게 나을 것 같아 아래에 코드를 첨부하였다. 

 

<Cat.kt>

data class CatEntity(
	val name: String,
    val age: Int,
    val color: String
)

6. Repository

  Domain Layer와 Data Layer사이에서 중재하는 역할을 한다. 즉, ViewModel이 데이터를 요청하면 Repository는 내부 디비인 SQLite, Room 이나 Retrofit 을 이용해 서버로부터 데이터를 갖고온다. 이렇게 되면 ViewModel은 데이터를 어디서 갖고오는 지 몰라도 자기가 수행해야 하는 비즈니스 로직만 처리하면 된다.

 

(위의 그림처럼 ViewModel이 비즈니스 로직을 수행한다면, Data Source, Model이 데이터를 제공하고, Repository는 중간에서 데이터를 받아와 전달하는 역할이라고 이해했다..)

 

7. Data Source

  데이터는 Local에서 (cached, 내부 DB) 가져올 수도 있고, Remote(서버, 소켓 등) 에서 가져 올 수 있다. 

 

 

Reference

https://devvkkid.tistory.com/196

https://proandroiddev.com/clean-architecture-data-flow-dependency-rule-615ffdd79e29

https://imcreator.tistory.com/105

https://black-jin0427.tistory.com/225

https://developer88.tistory.com/210

https://vagabond95.me/posts/android-repository-pattern/ 

https://charlezz.medium.com/viewmodel%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80-viewmodel-%EC%B4%88%EB%B3%B4%EB%A5%BC-%EC%9C%84%ED%95%9C-%EA%B0%80%EC%9D%B4%EB%93%9C-e1be5dc1ac18

 

 

 

 

Comments