안드로이드 MVVM (비교 MVP)이란?

쓰리원·2023년 1월 1일
0

android architecture

목록 보기
2/3
post-thumbnail

위 글을 이해하기 위해 필요한 사전 지식

1. LiveData란?
2. Backing Properties 란?

1. 안드로이드 디자인 (아키텍처) 패턴이란?

이번 글에서는 MVVM을 중심으로 알아보도록 하겠습니다. MVVM과 MVP와의 비교를 통해서 MVVM으로 얻을 수 있는 이점이 무엇인지 더 깊은 이해를 할 수 있을 것 입니다. 이전글에 MVC와 MVP를 비교한 글이 있습니다. 읽고 위 글을 읽으면 도움이 될 것 입니다.

1. MVC (Model - View - Controller)
2. MVP (Model - View - Presenter)
3. MVVM (Model - View - ViewModel)

위의 아키텍처를 보시면 전부 다 View와 Model이 존재합니다. 앱을 제작하는데 있어서 사용자에게 보여주기위한 UI(View)와 그리고 View를 이루는 Data(Model)는 항상 존재하기 때문입니다. 그러므로 View와 Model 사이의 의존성이 생길 수 있다고 유추 할 수 있습니다.

  • View : 사용자에게 제공되어 보이는 UI 부분이라고 볼 수 있습니다. 앱의 화면은 이 View에 해당합니다
  • Model : 애플리케이션에서 사용되는 데이터 입니다. 데이터 조작 로직을 처리하는 부분으로 사용되기도 합니다.

2. MVC, MVP, MVVM 비교

위 그림을 보면 MVC와 MVP의 차이점 하나를 발견할 수 있습니다. 그것은 바로 Model이 View에 직접적으로 관여를 하냐 안하냐의 차이입니다. 그리고 MVP와 MVVM의 그림을 보면 구성이 상당히 비슷한 것을 볼 수 있습니다. 그러나, Presenter가 ViewModel로 바뀌고, Update UI는 Notify State로 바뀐 것을 볼 수 있습니다. 이러한 변화가 우리가 알아야할 핵심 포인트라고 볼 수 있습니다.

3. MVVM 이란?

  • MVVM (Model - View - ViewModel)

Model과 View에 대한 설명은 위의 설명과 동일하기 때문에 생략하겠습니다. MVVM의 경우는 ViewModel이라는 것이 있는데 이것이 무엇인지에 대해 설명하겠습니다.

  • ViewModel 란?

MVVM에서 ViewModel은 Presenter와 마찬가지로 Mediator(중재자) 역할을 담당합니다. 차이점은 View와의 관계에서 ViewModel은 단방향, Presenter는 양방향 처리을 합니다. 즉, Presenter는 View에게 뷰 변경 요청을 보내지만, ViewModel은 View에게 어떠한 요청도 보내지 않습니다.

View가 ViewModel의 데이터를 관찰하다 변경되면 변경을 적용할 뿐 입니다. 그래서 코드 상에선 View가 ViewModel을 호출해 observable or callback 형태로 받습니다. 이 부분에 대해서는 글로만은 이해가 안되는 부분이 있을 것입니다. 예제를 통해서 알아보면 좋을 것 같습니다.

  • MVVM 패턴 장점
  • Separation of Concerns : 비즈니스 로직과 뷰 로직이 나뉘어 지기 때문에 비대한 액티비티/프레그먼트를 어느정도 막을 수 있습니다. 게다가 자주 사용되는 뷰모델의 경우 재활용도 가능할 수 있기 때문에 유지보수에 유리 할 수 있습니다.

  • Data Binding : 데이터 바인딩을 통해 View와 ViewModel 사이의 동기화를 자동으로 처리할 수도 있습니다. 이로인해 코드가 간결해질 수도 있긴하지만, 안드로이드 경우 xml 에서 observer pattern 이 코드 추적이 어려울 수도 있고, 관리가 복잡할 수 도 있기 때문에 저 같은경우는 뷰바인딩을 적극적으로 활용하며 State의 반환으로 추가적인 코드는 View 에서 작성하게 합니다.

  • Testability : ViewModel은 View에 대한 의존성이 없으므로 독립적으로 테스트할 수 있습니다.

  • MVVM 패턴 단점
  • Complexity : MVVM 패턴은 다른 패턴에 비해 복잡하고, 이해하고 구현하는 데 시간이 더 필요합니다. MVVM은 데이터 바인딩과 같은 고급 기법을 사용하기 때문에, 초기에 배우기 어려울 수 있습니다. 따라서 팀 전체가 MVVM에 익숙해지는 데 시간이 필요할 수 있습니다.

  • Overkill for Simple UIs : 간단한 UI를 가진 작은 앱에 MVVM을 사용하는 것은 과도한 설계로 볼 수 있습니다. 이런 경우에는 MVC 또는 MVP와 같은 더 간단한 패턴을 사용하는 것이 적합할 수 있습니다.

4. MVVM 코드 예제

1. MainViewModel

class MainViewModel
@ViewModelInject
constructor(
    private val mapApiRepositoryImpl: MapApiRepository
) : ViewModel() {

	....
    
    private val _locationData = MutableLiveData<MainState>(MainState.Uninitialized)
    val locationData: LiveData<MainState> = _locationData
    
    ....
    
}

Backing Properties 형태로 LiveData를 구현을해서 LiveData의 상태를 MainActivity에서 임의로 수정할 수 없게 만들어 줍니다. 이렇게 하면 MainActivity에서는 LiveData의 data 상태의 변화만 읽고 상태에 따라 View와 data를 업데이트 하게 됩니다. Backing Properties가 무엇인지 추가 적인 내용은 위의 선수 지식의 링크를 통해서 공부 할 수 있습니다.

2. MainActivity

class MainActivity : AppCompatActivity() {

	....
    
    private val viewModel: MainViewModel by viewModels()
    
        @SuppressLint("MissingPermission")
    	override fun onCreate(savedInstanceState: Bundle?) {
        
        	....
        
        	super.onCreate(savedInstanceState)
        	binding = ActivityMainBinding.inflate(layoutInflater)
        	setContentView(binding.root)
        	observeData()
            
            ....
    	}
        
        private fun observeData() = with(binding) {

        	viewModel.locationData.observe(this@MainActivity) {
            	when (it) {
                	is MainState.Uninitialized -> {
                    	if(viewModel.getMyLocation(this@MainActivity)) {
                        	permissionLauncher.launch(PERMISSIONS)
                    	}
                	}

                	is MainState.Loading -> {}

                	is MainState.Success -> {
                    	locationLoading.isGone = true
                    	locationTitleTextView.text = it.mapSearchInfoEntity.fullAddress
                    	viewModel.setDestinationLocation(it.mapSearchInfoEntity.locationLatLng)
                	}

                	is MainState.Error -> {
                    	locationTitleTextView.text = getString(it.errorMessage)
                	}
            	}
        	}
    	}
        
        ....
}

MainViewModel의 LiveData가 Backing Properties로 구현 되어있고, MainActivity에서는 Observing을 통해서 LiveData의 변화를 sealed Class의 state에 따라서 구분해서 UI 갱신 및 비즈니스 로직을 실행하는 것을 볼 수 있습니다.

5. MVVM 과 MVP 비교

공통점

  • MVVM과 MVP는 둘 다 사용자 인터페이스(View)와 비즈니스 로직(Model)을 분리하고 테스트 가능한 코드를 작성할 수 있게 해줍니다.

  • 비즈니스 로직과 UI를 분리하여 애플리케이션의 복잡도를 줄여서 유지보수를 용이하게 합니다.

차이점

  • MVVM은 데이터 바인딩을 사용하여 View와 ViewModel을 바인딩하고, ViewModel이 Model과 상호작용하여 View에 반영합니다. MVP는 Presenter가 Model과 View 사이에서 중개자 역할을 하고 View와 Model이 서로 의존성을 가지지 않도록 구성합니다.

  • MVVM에서는 ViewModel이 데이터를 관리하고 View와의 연결을 처리합니다. MVP에서는 Presenter가 View와 Model 사이에서 중개자 역할을 하기 때문에 View와 Model이 서로 의존성을 가지지 않습니다.

  • MVVM에서는 View와 ViewModel 간의 데이터 바인딩을 사용하여 View를 업데이트합니다. MVP에서는 Presenter가 View를 업데이트합니다. 따라서, MVVM은 데이터 바인딩을 사용하여 코드를 단순화하고 유지보수성을 높이는 반면, MVP는 Presenter를 통해 View와 Model을 엄격하게 분리하고, 유지보수성을 높이는 것을 목적으로 합니다.

6. reference

  • My brain
profile
가장 아름다운 정답은 서로의 협업안에 있다.

0개의 댓글