Kwaang Tech

MVC, MVP, MVVM, MVI 본문

Dev/Study

MVC, MVP, MVVM, MVI

콰앙 2023. 9. 14. 19:56

앱 아키텍쳐 패턴

안드로이드 앱을 개발할 때, 이용할 수 있는 여러 아키텍쳐 패턴들이 있다.

  • MVC (Model View Controller)
  • MVP (Model View Presenter)
  • MVVM (Model View ViewModel)
  • MVI (Model View Intent)
  • 기타

이름들을 보면 M(Model)과 V(View)를 공통적으로 가지고 있다.

  • Model - 데이터 or 데이터를 생성하거나 업데이트
  • View - UI or 화면을 표시

Logic들이 커지고 복잡해짐에 따라서 의존성이 더 강해지고, 결국 앱을 유지 보수하기가 점점 더 어려워 지게 된다.

이러한 문제들을 해결하기 위해 여러 패턴들이 나왔고, 결국 M-V 사이의 관계를 어떻게 처리하느냐에 따라 패턴들을 구분을 짓는다.

 


MVC(Model View Controller)

프로그램을 각각의 역할에 따라 Model, View, Controller 로 나누어 설계한 아키텍쳐 패턴

MVC

  1. 모든 입력들은 Controller 로 전달된다.
  2. Controller는 입력에 해당하는 Model을 업데이트 한다.
  3. 업데이트 결과에 따라 View를 선택한다. (하나의 Controller는 View를 선택할 수 있기에, 1:n의 관계로 여러개의 View를 관리할 수 있다.)
  4. Controller는 View를 선택만 할 뿐, 직접 업데이트는 하지 않는다.
  5. View를 업데이트 하기 위해서는 여러가지 방법들이 있다.
    • View가 Model을 직접 이용하여 업데이트
    • Model에서 View에서 Notify하여 업데이트
    • View가 Polling 하여 Model의 변화를 감지해서 업데이트
더보기

Notify

  • Model 이 View에게 특정 이벤트나 상태 변경이 발생했음을 직접 알린다.
  • 방식은 일반적으로 푸시(Push) 메커니즘으로 알려져 있다. 변경 사항이 발생할 때마다 알림이 전송된다.

Polling

  • View가 주기적으로 또는 연속적으로 Model의 상태를 확인한다.
  • 즉, View가 일정한 간격으로 Model에 "변경사항이 있어?" 와 같은 질문을 한다.
  • 이 방식은 View가 필요할 때마다 정보를 요청한다.

이 두가지 방식에는 장단점이 있다.

  • Notify는 실시간 업데이트가 필요할 때 유용하지만, 너무 자주 변경 사항이 발생하면 알림 과도하게 발생할 수 있어 시스템의 효율성을 저하시킬 수 있다.
  • Polling 은 간단하게 구현할 수 있지만, 너무 자주 폴링하면 불필요한 시스템 부하가 발생할 수 있다. 반면에 너무 드물게 풀링하면 중요한 업데이트를 놓칠 수 있다.

 

View를 업데이트 하기 위해서는 결국 M - V 사이에 의존성이 존재하기 된다. 안드로이드 Activity(Fragment)가 Controller 와 View를 모두 처리하기 때문에, 한 클래스에서 M-V-C 모두 처리하게 되는 문제점이 발생한다.

 

MVC는 가장 단순한 패턴을 가지고 있는 장점이 있고,  Model과 View사이의 의존성이 발생해서 앱이 커지고 복잡해질수록 유지보수가 어렵다는 단점을 가지고 있다.

 


MVP(Model View Presenter)

MVC에서 파생된 Model과 View간의 의존성이 없는 아키텍처 패턴

MVP

 

  1. 모든 입력들을 View로 전달된다.
  2. Presenter 는 입력에 해당하는 Model 을 업데이트 한다.
  3. Model 업데이트 결과를 기반으로 View 를 업데이트 한다.
  4. Presenter 는 해당 View 를 참조하고 있다. (View 와 Presentersms 1:1 관계)
  5. Presenter 는 ViewModel 인스턴스를 가지고, Model 과 View 사이의 매개체 역할을 한다.
Presenter 가 M-V 사이에서 관리를 해주기 때문에, MVC 패턴과는 달리 M-V 사이의 의존성이 없지만,
앱이 커지거나 복잡해질수록 V-P간의 의존성이 강해지는 문제점이 발생한다.

 

MVP는 Model 과 View 사이의 의존성이 없는 장점이 있지만, View 와 Presenter 가 1:1 관계이기 때문에 서로 의존성이 커지고 필요한 클래스 개수가 많아지는 단점이 있다.

 


MVVM(Model View ViewModel)

MVC에서 파생된 Model 과 View 간의 의존성뿐만 아니라 Controller 와 View 간의 의존성도 고려하여 각 구성 요소가 독립적으로 작성되고 테스트될 수 있도록 설계된 아키텍처 패턴

MVVM

  1. 모든 입력들은 View 로 전달된다
  2. ViewModel 은 입력에 해당하는 Presentation Logic 을 처리하여 View 에 데이터를 전달한다.
  3. ViewModelView 를 참조하지 않기 때문에 독립적 (ViewModel 과 View는 1:n 관계)
  4. 따라서 View 는 자신이 이용할 ViewModel 을 선택해 바인딩하여 업데이트를 받게 된다.
    (Command 패턴이나 Data Binding을 이용하여 V-VM 간 의존성을 없앨 수 있다.)

    ※ Command 패턴은 디자인 패턴 중 하나로, 요청 자체를 객체로 캡슐화하는 것
  5. Model 이 변경되면 해당하는 ViewModel 을 이용하는 View 가 자동으로 업데이트 된다.
  6. ViewModel 은 View 를 나타내 주기 위한 Model 이자, View 의 Presentation Logic 을 처리한다.
MVP 와 마찬가지로 M-V 사이의 의존성이 없고, MVP 처럼 V-P 이 1:1 관계가 아닌 독립적이기 때문에 이 둘 사이의 의존성도 없다.

 

MVVM 은 Model 과 View 사이에 의존성이 없고, ViewModel 과 View 의 의존성도 없으며 중복되는 코드를 모듈화 할 수 있는 장점이 있다. 반면에 ViewModel 설계가 쉽지 않다는 단점이 있다.

 


MVI(Model View Intent)

자바스크립트 생태계에서 탄생했으며, MVC에서 파생된 능동적인 Controller 대신 Intent 라고 불리는 Reactive 요소를 이용한 아키텍처 패턴

MVI

MVC 에서 Controller 가 직접 Model 을 업데이트 하고 View 를 선택하는 능동적인 구조가 아닌, MVI 는 Intent 가 User 를 관찰하고, ModelIntent 를 관찰하고, View 가 Model 을 관찰하고, User 가 View 를 관찰하는 Reactive  요소로 이루어져 있다. 따라서 안드로이드에서는 RxJava 같은 라이브러리가 필수적이다.

 

MVI (Model-View-Intent)와 같은 아키텍처에서 RxJava는 Model, View, Intent 간의 데이터 흐름을 정의하고 관리하는 데 중요한 역할을 합니다. MVI는 이러한 반응적 패러다임에 크게 의존하며, RxJava는 이를 구현하는 데 매우 유용한 도구
  1. Intent 로 User 로부터 입력을 가져온다. (여기서 Intent는 안드로이드의 Intent와 다름)
  2. Intent 는 Model 에서 처리해야 하는 동작(Intended action)을 제공한다.
  3. Model 은 Intent 로부터 동작을 가져온다. (MVI 의 Model은 단순 데이터뿐 아니라, app 상태(state) 와 Business Logic을 관리한다.)
  4. Model 은 View 에 표시할 새로운 모델을 생성한다.
  5. View 는 Model 로부터 새로운 모델을 가져와 표시한다.
Android 에서 발생할 수 있는 여러 이슈들(화면회전, BackStack, Process death 등)로 인해 코드들이 복잡해지기 쉬운데, MVI단방향 데이터 흐름과 불변성으로 인해 예측 가능한  상태가 만들어지기 때문에 유지보수가 좀 더 용이해 지는 장점이 있다.

 

MVI 는 단방향, 불변성 데이터를 이용해 예측 가능한 상태로 만들어지고, 서로 간에 의존성이 없는 장점이 있지만, RxJava 와 같은 Observable 한 외부 라이브러리를 이용해야 하는 단점이 있다.

반응형