본문 바로가기

iOS

왜 MVVM 을 사용할까요?

이 포스트는 기본적인 MVVM 의 지식을 알고 있다는 가정하에 설명되며 

개인적인 의견이 많이 포함되어있습니다.

 

왜 MVVM 을 사용할까요?

 

https://www.zkoss.org/wiki/ZK_Developer%27s_Reference/MVVM

 

저는 개인적으로 3가지 이유를 들수 있습니다.

 

1. 구체적인 View 를 알지 못하더라도 요구사항에 따라 ViewModel 을 설계할 수 있습니다. 

2. ViewModel을 재사용 단위로 설계할 수 있습니다.

3. Testable 합니다.

 

Github Repositories 를 검색할 수 있는 기획이 있다고 가정해 봅시다.

 

 

구체적인 View 를 알지 못하더라도 요구사항에 따라 ViewModel 을 설계할 수 있습니다. 

우리는 위에 간단한 Demo 에서 4가지 Case 의 요구사항을 정의할 수 있습니다.

1. Repository는 이름으로 검색할 수 있습니다.

2. 검색을 하면 Loading 이 보여줘야 합니다.

3. 검색된 결과는 Repository Name, Owner Name, Star Count, Fork Count 4가지 항목이 리스트 형태로 보여줘야 합니다.

4. 검색 도중 에러가 발생하면 사용자에서 Alert 를 띄어야 합니다.

 

 

우리는 UseCase 에서 Input, Output 의 요소를 뽑아낼 수 있습니다.

Input:  Search Field, 검색 버튼 

Output: 리스트 형태의 결과, Error Alert

 

위의 Input Output 의 UseCase 를 바탕으로 View와의 의존성이 없는 ViewModel 을 설계할 수 있습니다.

 

 

즉, 구체적인 View를 알지 못하더라도 DataBinding 을 통해 View의 행위를 시킬 수 있습니다.

 

Client(ViewController) 에서는 ViewModel 상태 변화에 따라 View 를 제어합니다.

 

 

View 와의 의존성을 없애기 위한 노력은 개인적으로 이렇게 생각이 듭니다.

 

1. Test 환경에서 UI Framework 를 의존하는데 많은 비용이 들어갑니다.

iOS 는 UI가 UnitTest 단위로 테스트하는 것이 가능하지만 다른 Android의 경우는 다릅니다.

 

한번의 테스틑 위해"빌드 > 설치 > 테스트 과정"을 수행하는데 1분 이상 걸린다고 생각해보세요.

 

개발자 세계에서 시간이 곧 돈이기 때문에 많은 비용이 들어간다는 것은 치명적입니다.

 

Android TestCode 를 포스트에서는 UI를 테스트 가능하도록 만들기 위하여

* Espresso

* Robolectric

* UIAutomator

UI Testing Framework 를 의존해야만 UI Test 가 가능합니다.

 

2. UI는 가장 빈번하게 변경이 일어납니다.

 

아래 그림은 Clean architecture 참고한 것 입니다.

 

각 UI, Presenter, Use Cases, Entities 의 Layer 가 존재하며 의존성에 방향이 아래로 향하고 있는 것을 알 수 있습니다.

즉, Entities 가 변경되면 Entities 를 의존성하고 있는 상위 Layer 들은 변경이 필요할 수 있다는 것을 의미합니다.

 

사용자와의 접점인 UI는 가장 상위 Layer 입니다.

상위 Layer 일수록 코드의 변경이 가장 빈번하게 일어날 수 있다는 것이 개인적인 의견입니다.

Testable 합니다.

View와 의존성이 없기 때문에 UnitTest 단위로 View의 행위를 검증할 수 있기도 합니다.

 

UseCase 2가지에 대해 테스트 코드를 작성할 수 있습니다.

1. Repository는 이름으로 검색할 수 있습니다.

2. 검색을 하면 Loading 이 보여줘야 합니다.

 

위에 TestCase를 풀어서 설명드리겠습니다.

 

Given:

search(sortOption:)을 호출하면 성공하는 Mock 객체를 만듭니다.

 

When:

"test" 검색어를 입력하고 검색 버튼을 누릅니다.

 

Then:

* isLoading은 true, false 상태가 변화해야합니다.

* service의 search(sortOption:) 은 1번 호출되어야 합니다.

 

우리는 방금 Presenter Layer 에 대해 TestCase를 작성하였습니다.

Test Code의 전체소스는 여기에서 확인할 수 있습니다.

 

MVVM 과는 상관없지만 View의 Test Code를 어떻게 작성할 수 있을까요?

 

View TestCase의 전체소스는 여기에서 확인할 수 있습니다.

 

View에서 Test Case를 작성하는 예시

UICollectionCell 의 repositoryName text 가 "test" 인지? 

UILabel textColor 가 white 인지?

 

ViewModel을 재사용 단위로 설계할 수 있습니다.

MVVM은 View 1 : N ViewModel 관계를 맺을 수 있습니다.

 

현재는 Repository 를 검색하는 ViewModel만 존재합니다.

"Code로 검색을 할 수 있다" 라는 요구사항이 추가되었다고 가정해봅시다. 

Github Search Code API

 

그러면 기존의 ViewModel 의 코드를 변경하는 것이 맞을까요? 

 

만약 기존의 Repository 를 검색하는 로직의 코드까지 변경된다면

ViewModel에 대해 지금까지 진행했던 회귀 테스트는 무효화 될 것 입니다.

즉, 다시 처음부터 테스트를 진행해야 합니다. 

 

SearchCodeViewModel 라는 이름의  ViewModel을 새로 만들고 ViewController에서 사용할 수 있도록 제공하는 것이 

코드의 변경을 최소화 할 수 있는 방법입니다.

 

뿐만 아니라 재사용의 이점이 있습니다.

다른 화면에서 Code를 검색할 수 있는 기능의 요구사항이 있다면 SearchCodeViewModel 만 Binding 시키면 되니까요.

 

 

 

 

부족하지만 시간내어서 읽어주셔서 감사합니다.

 

전체코드는 여기에서 확인할 수 있습니다.

 

소중한 시간 내주셔서 감사합니다