개발

MVC, MVVM, MVP

 Spring MVC로 졸업작품을 수행할 예정이여서, MVC패턴을 정리해야겠다고 마음먹었습니다. 또한 Vue.js로 WebSocket과 RestAPI로 받은 데이터를 차트로 그리는 프론트 프로젝트를 수행하며 MVVM패턴에 대해 공부해 볼 기회가 있었습니다.

출처: https://blog.xenomity.com/MVWModel-View-Whatever%EC%9D%98-%EC%9D%B4%ED%95%B4/

MVC에서 파생된 MVP/MVVM 패턴은 관심사의 분리를 통한 Model, View 사이의 결합도를 줄이고 기능 단위의 응집도를 높이기 위한 관점으로 MVC 목표하는 바가 같습니다. 목적을 위해 패턴은 View Model 사이의 상호 작용을 위한 component Controller/Presenter/View-Model이라는 이름으로 표현하고 있습니다.


1) MVC

Controller와 View는 1:n 관계입니다. Controller는 알맞은 View를 선택합니다. 하지만, 이때 View는 Controller를 알 수 없습니다. Controller는 사실 어떤 페이지를 제공할지 렌더링해서 데이터와 함께 응답합니다. 즉, 실제로 View에서 Model을 이용하기 때문에 View와 Model의 의존성의 분리는 쉽지 않습니다. 

 

조금 이해를 높여보고자, 예시를 들어보겠습니다.

 

1. https://www.tistory.com/에 접속한다고 가정해봅시다.

 

2. Controller는 사용자의 요청을 서비스 하기 위해서 모델을 호출합니다.

 

3. Model은 데이터베이스에서 가져온 Data를 반환합니다.

 

4. ControllerModel이 반환한 결과를 View에 반영합니다.

 

5. 사용자는 서버에서 응답한 결과를 볼 수 있습니다.


다음으로, Spring MVC에서는 실제로 어떠한 흐름으로 동작하는지 잘 설명한 페이지가 있어 정리해보고자 합니다.

출처: http://codehungry.blogspot.com/2017/12/explain-complete-spring-mvc-flow.html

1. Browser에서 Spring MVC 웹 어플리케이션에 요청을 보냅니다.

 

2. Dispatcher Servlet(Front controller) 는 최앞단에서 그 요청을 캐치한 후 Security, Logging, Auditing 등의 보통의 서비스들을  응답합니다.

 

3. Dispatcher Servlet은 Handler Mapping 으로 그 요청을 위임합니다. (인터넷에 있는 자원을 나타내는 유일한 주소인URI를위임)

 

4. Handler Mapping이 요청(req)을 Handler/Controller class와 맵핑 되는 핸들러 클래스의 Bean Id를 반환합니다. 디스패처 서블릿은 Bean ID로 해당 핸들러 클래스 객체를 가져오고 해당 오브젝트 메소드를 호출하며 Handler Class가 제어권을 갖습니다.

 

5. Handler/Controller class는 Command class 객체를 생성하고 Request wrapping을 수행합니다. (form data가 있다면 이를 받고 requestWrapping 즉 Command Class 객체에 저장합니다.)

 

6. 이제 Handler Class는 비즈니스 로직을 실행하거나 서비스 또는 DAO 클래스가 요청을 수행하도록 해 결과를 받습니다.

 

7. Handler Class Logical View Name(LVN) Dispatcher Servlet 반환합니다.

 

8. Dispatcher Servlet은 LVN을 통해 Physical View를 갖는 View 인터페이스 구현 클래스 객체 반환 합니다.

Dispatcher Servlet은 View Resolver 통해 View Object 를 가져옵니다 .

 

9. Dispatcher Servlet 해당 View Obj에서 Render() 메소드를 call합니다.

 

10. 이제 Render() 메소드는 View Resouce로 제어권을 전달하고 JSP나 html 등 physical view를 가져옵니다.

 

11. View Resource는 프레즌테이션 로직을 포함하고 형식화한 결과를 응답으로 브라우저에 보냅니다.


2) MVP

출처: https://brunch.co.kr/@oemilk/75

입력이 View에서 처리됩니다. 

Presenter, View1:1관계

View에서 전달받은 event에 따라 PresenterModel에 data를 요청합니다.

• Android에서 MVP 패턴의 ViewMVCView와 조금 다르게 activityfragmentView 의 일부로 간주합니다.

 

MVP 패턴은 ViewModel 간의 의존성을 분리시킨 점이 MVC와 다르게 보입니다. 또 다른 점은 MVC에서는 사용자 Input에 Controller가 먼저 반응하고 View를 해당하는 작업을 서비스한 후 반환합니다. MVP에서는 사용자 input에 View가 처음 반응하고 Presenter에 알린 후 처리한 작업을 다시 View에게 전달합니다. 그러나, MVP패턴은 View와 Presenter의 관계가 1:1로 두 사이의 의존성이 깊어질 수 밖에 없는 단점이 생깁니다. View는 Presenter를 호출해야하고 Presenter는 View를 호출해야 되기 때문에 여기서 의존성의 문제가 발생할 수 있습니다.


3) MVVM

출처: https://joshua1988.github.io/web-development/vuejs/vuejs-tutorial-for-beginner/

MVP와 같이 View에서 입력이 처리된다.

ViewModelView를 나타내기 위한 Model

입력이 들어오면 Command 패턴을 통해 ViewModel에 명령을 내리게 되고 ViewModelModel에게 필요한 데이터를 요청

ModelViewModel에 필요한 데이터를 응답하고 Data Binding을 통해 ViewModel의 값이 변화하면 바로 View의 정보가 바뀜

ViewModel의 재사용성이 높으며, 단위 테스트가 수월

 

<흐름>

View에 요청이 들어오면 Command를 통해 ViewModel로 보낸다.

ViewModelModel에 데이터를 요청한다. 그리고 Model은 데이터를 응답한다.

이를 받은 ViewModel은 데이터를 가공한다.

ViewViewModel과의 Data Binding을 통해 데이터를 자동으로 갱신한다.

 

Vue.js에서 new Vue() 를 통해 초기 객체를 선언해줌으로써 뷰와 모델 사이에서 양방향 데이터 바인딩이 가능하게 해준다.

 

'개발' 카테고리의 다른 글

Spring IoC 용어 정리  (0) 2020.01.02