본문 바로가기
프로그래밍 놀이터/안드로이드, Java

[android] What is MVI & Concept of Model - MVI (Model View Intent) Architecture

by 돼지왕 왕돼지 2023. 11. 29.
반응형

What is MVI?

-

MVI 는 Model-View-Intent 를 의미하며, Cycle.js 에 영향을 받았다.

MVI 는 android 를 비롯한 UI-based app 에 적합한 패턴이다.

MVI 의 목적은 더 읽기 좋은 코드, decouple 된 코드이며, 더 일관성 있는 코드이다.

 

 

-

Intent 는 유저 이벤트에 의해 발생하는 view 와의 interaction 이다.

Intent 는 Model 의 상태변화를 야기한다.

 

-

View 는 다른 아키텍처에서 말하는 것과 동일하다.

Model 의 상태를 반영하며, intent 를 통해 유저 interaction 을 전달한다.

 

-

Model 은 'state' 를 의미하며, business logic 과의 interaction 을 포함한다.

이는 'unidirectional data flow' 를 위해 immutable 해야만 한다. 

Model 은 View 를 업데이트 하는 데 사용된다.

 

 

Android 에서의 Model

-

Android 에서의 Model 은 다음의 문제들을 해결해야 한다.

1. 상태 문제

2. 화면 방향 전환 문제

3. stack 간의 navigation 문제

4. process kill

5. immutability & unidirectional data flow

6. Debuggable and 재현가능한 상태

7. Testability

 

-

Model 은 business logic 을 이야기하지 않는다.

Model 을 생성해내는 것이 business logic 이다.

 

1. The State Problem

-

MVP 와 MVVM 은 view 가 event 를 presenter 나 viewModel 에 전달함으로써 input 을 많이 받는다. 그리고 output 역시 많다. presenter 는 view 로 직접 명령을 내리고, viewModel 은 observable 을 통해 값 발행을 통해 명령한다.

이 과정에서 MVP 또는 MVVM 의 전체 상태가 흐트러지기 쉽다. 특히 multi thread 환경에서 그렇다.

그리고 multi thread 이슈는 재현하기도 쉽지 않다는 또 다른 단점을 갖는다.

 

-

만약 우리가 믿을만한 bottom(Business Logic)에서 top(View)로 전달되는 하나의 상태를 갖는다면 어떨까?

이것이 Model 로 가능해지며 MVI 에서의 핵심 중 하나이다.

class PersonsModel(val loading:Boolean, val persons:List<Person>, val error:Throwable)

이를 보면 Model 이 상태를 투영한다.

Model 이 상태를 반영하게 되면서 Presenter 가 View 에게 전달하는 것은 이 모델 하나가 된다.

getView().render(PersonModel) 이런 식으로..

 

2. Screen orientation changes

-

MVP 에서는 presenter 를 유지했다가 다시 view 를 binding 시키고, MVVM 에서는 subscribe 를 다시함으로 상태 복구가 가능했다.

MVI 에서의 Model 이 상태를 가지므로 마지막 상태를 보관만 한다면 바로 마지막 state 보장이 가능해진다.

 

3. Navigation on the back stack

-

2 와 동일한 내용이다.

 

4. Process death

-

Model 하나가 state 를 기술하기 때문에 onSaveInstanceState 등의 이벤트에 이 녀석 하나만 저장하고 복구하면 된다.

(물론 process kill 시 상태를 저장하는 것이 능사는 아닐 수 있지만, 간편함을 이야기한다.)

 

5. Immutability and unidirectional data flow

-

Immutable & 하나의 Model 은 single source of truth (믿을 수 있는 하나의 소스)를 보장해준다.

 

6. Debuggable and reproducible states

-

단방향 data flow 는 디버깅을 쉽게 해준다.

 

7. Testability

-

Model 이 State 를 표현하면서 test 는 훨씬 쉬워진다.

마지막에 확인할 것은 assertEquals(expectedModel, model) 이 되면 된다.

이 테스트 하나가 Mockito.verify(view, times(1)).showFoo() 등의 검증을 갈음할 수 있다.

test 코드의 가독성도 좋아진다.

 

 

MVI 의 장단점

장점

- 상태관리가 쉬움. 상태에만 주목하면 됨.

- Unidirectional 이고, 전달대상이 하나라 data flow 쫓아가기 좋음.

- State object 가 immutable 이고 하나라 thread safety 측면에서 좋음.

- 디버그가 쉬움. 에러가 발생한 state 만 집중해서 보면 됨.

- Decouple 됨. 책임을 나누기 쉬움.

- Test 도 쉬움. 각각의 상태 테스트만 하면 됨.

 

단점

- State 관리에 boilerplate 가 많이 들어갈 수 있음.

- 모든 state 를 만드는 것이 쉽지 않음. 가끔은 memory 관리 측면에서도 이슈가 될 수 있음.

- 1회성 event 들에 대한 관리가 어려움 -> SideEffect 개념으로 해결?

 

 

참고 자료

http://hannesdorfmann.com/android/mosby3-mvi-1

https://www.novatec-gmbh.de/en/blog/mvi-in-android/

https://blog.mindorks.com/mvi-architecture-android-tutorial-for-beginners-step-by-step-guide/

 

끝.

 

반응형

댓글