본문 바로가기

[C#] MVC, MVP, MVVM는 뭐지?

I'm 영서 2024. 1. 16.
반응형

 

 

기존에 Winform만 사용하다보니 WPF를 사용하게 될때 Winform과 같이 사용하다 보니

협업시 문제가 생기는 경우가 종종 발생했다. MVVM 이라는 패턴을 잘 사용해야한다고 하여 알아보니

구조 디자인 패턴이라고 한다. 찾아보니 MVC, MVP, MVVM... 등등 다양하게 있는데, 한번 알아보자.

 

 

구조 디자인패턴 

사전적 의미는 클래스나 객체의 구성을 통해 더 큰 구조로 만들 수 있게 해주는 패턴이다.

 

MVC, MVP, MVVM은 이 구조 디자인 패턴에 들어가 있는 개념으로

 

이런 디자인 패턴은 개발, 소통 등의 확실한 편리함을 가진다. 

 

그렇다면 MVC, MVP MVVM은 무엇일까?

 

알아보기에 앞서 왜 디자인 패턴이 필요한지에 대해 생각해보자

 

현업에서 일을 하다보면 중간에 기획이 변경되거나 디자인 시안이 변경되는 일은 아주아주 흔한 일이다.

이때 디자인이 변경되어 있던 액션버튼이 사라지거나, 혹은 변경되는 경우 기존의 방식의 경우 하나로 연결되어있어 

그대로 문제가 발생한다. 

 

이러한 문제는 UI와 로직부분이 하나로 합쳐져있어 의존성이 높다는 것에서 생겨난 문제이고, 

때문에 UI와 로직 부분의 의존성을 낮추는것이 필요했기에 패턴이 생겨났다.

 

간단한 예와 함께 하나씩 알아보자. 재미없는 역사는 조금 접어두겠다.

예제는 다음과 같다.

간단한 쇼핑 리스트 어플리케이션
이번주에 사야할 항목의 이름, 개수, 가격의 목록을 관리한다.

 

MVC (Model • View • Controller)

https://developer.mozilla.org/ko/docs/Glossary/MVC 참고

Model :  어플리케이션이 포함해야할 데이터가 무엇인지 정의한다. 데이터의 상태가 변경되면 Model을 View에 알리며 (필요에 따라 화면을 변경) Controller에 알리기도 한다 (업데이트된 View를 조절하기 위해 다른 로직이 필요한 경우 ex.View에서 쇼핑 리스트를 보여주는데, 추가가 된 경우 View를 다시 그려주기도 한다. )

  

View : 어플리케이션의 데이터를 보여주는 방식을 정의한다. 쇼핑리스트 어플리케이션에서 View는 사용자에게 어떻게 보여질지를 정의하고, 표시할 데이터 Model에 접근하여 Controller를 통해 거쳐 받는다.

 

Controller : 어플리케이션의 사용자로부터의 입력에 대한 응답으로 Model 및 View를 업데이트 하는 로직을 포함한다.

쇼핑리스트는 항목을 추가하거나 제거할 수 있게 해주는 입력 폼과 버튼을 가지고 있고, 이러한 액션은 Model이 업데이트 되는것이므로, 입력이 Controller에 전송되고 Model을 처리한 후 업데이트된 데이터를 View로 전송한다. 

 

 

View에서 Model에 직접 접근하여 Model을 업데이트 한다고요? 이거 결합도 높은거 아니에요?

 

맞다. 

 

MVC는 View가 Model에 직접접근하여 업데이트한다.

또 어플리케이션이 복잡해지면 해질수록 Controller가 커지면서 유지보수의 용이성도 잃게 되며, Controller는 사실상 재사용이 거의 불가능하다. 

 

이러한 착안점에서 나온것이 바로 MVP 패턴 되시겠다.

 

MVP (Model • View • Presenter)

 

Model : 모델은 어플리케이션의 핵심 데이터와 비즈니스 로직을 정의한다. 데이터의 상태 변경 시, 모델은 관련된 View와 Presenter에 알린다. 


View : 뷰는 어플리케이션의 사용자 인터페이스를 정의하며, 데이터를 보여주는 방식을 결정한다. 사용자에게 어플리케이션의 상태를 시각적으로 표현하며 데이터를 표시하고, 사용자 입력을 감지하여 Presenter로 전달한다.

 

Presenter
프레젠터는 Model과 View 사이의 중재자 역할을 수행한다. 사용자 입력에 대한 응답으로 Model을 업데이트하고, 변경된 데이터를 View에 반영한다. 프레젠터는 비즈니스 로직을 포함하고, 모델과 뷰 간의 상호작용을 조정한다. View와 Model은 프레젠터를 통해 통신하므로 직접적으로는 서로에게 접근하지 않는다.

 

예를 들어, 쇼핑 리스트 어플리케이션에서 MVP 패턴을 사용하면 다음과 같은 동작이 이루어진다.

 - 사용자는 항목을 추가하거나 제거하는 입력을 수행한다.
 - 입력은 View에서 사용자로부터 받는다.
 - View는 해당 입력을 프레젠터(Presenter)로 전달한다.
 - Presenter는 입력에 따라 Model을 업데이트하고, 변경된 데이터를 다시 View로 전송한다.
 - View는 업데이트된 데이터를 사용자에게 표시한다.
- 이러한 방식으로 MVP 패턴은 어플리케이션의 데이터와 사용자 인터페이스를 분리하여 관리하고, 의존성을 관리하여 유지보수성을 향상시킨다. 

 

즉 Presenter가 View와 Model간의 중재자 역할을 수행하므로 View와 Model은 서로 독립적으로 테스트하고 재사용 할 수 있게된다.  

 

조금더 쉽게 설명하자면, 누군가가 View에서 뭘 건드려도, Presenter를 통해 전달하므로 MVC에서 발생하는 View와 Model의 충돌 문제는 없다는 말이 된다!

 

잠깐만요! 그러면 Presenter와 View는요? 

 

의존성이 있다... 

...그래서 파생된게 바로 MVVM이다.

 

MVVM (Model • View • ViewModel)

Model : 어플리케이션의 데이터와 비즈니스 로직. 데이터를 관리하고 업데이트한다. 

 

View :사용자 인터페이스. 화면 요소를 표시하고 사용자 입력을 받는다.

 

ViewModel : View와 Model의 중재자. View에 데이터를 제공하고 사용자 입력을 받아 Model을 업데이트한다. View에 표시할 데이터를 포함하고 데이터와 View간의 양방향 Binding을 통해 자동으로 업데이트된다. 이를 느슨한 결합이라고 한다.

 

MVVM 패턴의 주요 이점은 다음과 같은데. 

Presenter와 동일하게 View 와 Model간 의존성이 줄어들었다.

양방향 데이터Binding을 통해 데이터의 자동 업데이트와 뷰의 실시간 반영이 가능해졌다.

ViewModel은 여러 View에서 재사용 될 수 있으므로 코드 재사용성이 높다.

 

Presenter와 가장 크게 다른점은 View를 반드시 호출할 필요가 없다는 것이다. 

 

근데 그러면 ViewModel에서 View를 호출할 필요가 없으면 어떻게 데이터가 움직이는거죠? 그리고, 결국 이 방식도 의존성이 있다는 말이 아닌가요?

 

그렇다. 그렇지만 View와 ViewModel간의 느슨한결합을 통해 어느정도 해결했다. View와 ViewModel을 연결하지만 ViewModel은 View를 명시적으로 호출하거나 제어하지 않는다. ViewModel은 데이터만을 관리하고 View와 상호작용하는데 필요한 정보를 제공하게 되어 아주 느슨한 결합을 유지한다. 

 

View ↔️ ViewModel간 직접적으로 호출하지 않고 결합을 유지하는 기술은 바로 Binding이다.

 

Binding

Binding은 View와 ViewModel간의 연결을 설정하여, 데이터를 동기화하는 메커니즘을 제공한다. 

구현 단계는 다음과 같다. (WPF를 검색해보면 몇몇 단계와 구현체가 생각날 것이다) 

 

1. 데이터 소스 설정

 - ViewModel에서 제공하는 데이터를 데이터바인딩 시스템에 등록한다 (일반적으로 ViewModel의 속성으로 표현되며, View에서 사용할 데이터를 포함한다.)

2. 바인딩 설정

 - View의 요소(텍스트상자, 레이블, 리스트 뷰 등..)를 선택하여 이러한 요소와 ViewModel의 속성간 바인딩을 설정한다. 

3. 동기화

 - 데이터 바인딩 시스템은 View와 ViewModel간의 바인딩 설정을 감지하여 두쪽 간의 데이터를 동기화 한다. View에서 발생한 이벤트 또는 사용자 입력을 ViewModel에 전달한다.

4. 이벤트 처리

 - View에서  발생한 이벤트는 ViewModel로 전달되어 ViewModel에서 처리한다. 

5. 데이터 변경 감지

 - ViewModel의 속성이 변경되면 바인딩시스템은 이를 감지하여 View의 해당 속성을 업데이트 한다. 이로인해 View의 데이터의 실시간 반영이 가능하다.

 

 

이러한 방식으로 MVVM은 View와 Model, ViewModel간의 의존도를 최소화 하였고. WPF개발을 하면서 아주 많이 쓰이는 패턴이 되었다. 

 

간략한 구현예제는 다음포스트에.

반응형

댓글