---
# System prepended metadata

title: MVC

---

# MVC(Model View Control)

需要注意的是：MVC 不是一種技術，而是一種理念。

## View

能夠實現資料有目的的顯示（理論上，這不是必需的）。在 View 中一般沒有程式上的邏輯。為了實現 View 上的重新整理功能，View 需要訪問它監視的資料模型（Model），因此應該事先在被它監視的資料那裡註冊。

## 前後端分離情況下的MVC

![](https://hackmd.io/_uploads/HJMNxncla.png)
![](https://hackmd.io/_uploads/HyBaGn5ea.png)



## Spring Web MVC

@StanShih 

The formal name, "Spring Web MVC," comes from the name of its source module (spring-webmvc), but it is more commonly known as "Spring MVC".

在Spring的Web MVC框架提供了模型 - 視圖 - 控製器架構以及可用於開發靈活，鬆散耦合的Web應用程序準備的組件。 MVC模式會導致分離的應用程序（輸入邏輯，業務邏輯和UI邏輯）的不同方麵，同時提供這些元素之間的鬆耦合。

模型（Model ）封裝了應用程序的數據和一般他們會組成的POJO。

視圖（View）是負責呈現模型數據和一般它生成的HTML輸出，客戶端的瀏覽器能夠解釋。

控製器（Controller ）負責處理用戶的請求，並建立適當的模型，並把它傳遞給視圖渲染。


Spring的web模型 - 視圖 - 控製器（MVC）框架是圍繞著處理所有的HTTP請求和響應的DispatcherServlet的設計。 Spring的Web MVC框架的DispatcherServlet的請求處理流程說明如下圖：

![](https://hackmd.io/_uploads/B1Ae2j5gT.png)


Spring DispatcherServlet
下麵是對應於傳入的HTTP請求到DispatcherServlet的事件序列：

接收HTTP請求後，DispatcherServlet 谘詢 HandlerMapping 來調用相應的控製器。

該控製器接受請求並調用基於使用GET或POST方法相應的服務方法。服務方法將基於定義的業務邏輯設置模型數據，並返回視圖名到DispatcherServlet。

DispatcherServlet將需要幫助的ViewResolver從拾取到該請求所定義的視圖。

一旦視圖被敲定，DispatcherServlet會傳遞模型數據是在瀏覽器上最終呈現的視圖。

所有上述部件，即HandlerMapping，控製器和視圖解析器WebApplicationContext 部分是純的 ApplicationContext 必要的 Web應用程序的一些額外的功能擴展。

![](https://hackmd.io/_uploads/ryizcocx6.png)

![](https://hackmd.io/_uploads/ryEXqs5lp.png)



## MVVM
{%youtube -xTqfilaYow %}
* 組成
    **M = Module : 資料**
    大致與原先MVC中的M(Model) 是一樣的，用來資料儲存、資料型別定義
    只能與 ViewModel 進行溝通，不能與 View/ViewController 直接溝通
    **VM = ViewModule : 中間層，轉換原始資料成顯示用資料**
    負責將 Model 的資料轉換成 View/ViewController 所需的格式
    處理網路請求的部分
    **V = View : 頁面顯示**
    接收 ViewModel 的資料來做 UI 畫面呈現、與使用者互動
    只能與 ViewModel 進行溝通以及 Data Binding
    只能透過 ViewModel 來跟 Model 進行間接溝通

* 與MVC不同之處
MVC發展較早，當時候view的部分還相對今天簡單，所以著墨的比較少，多注重在於"全端"商業邏輯與資料庫的分離上。而View發展越來複雜之後，為了更方便的管理**前端資料與UI互動**，以及**複用component**，才出現MVVM。

* 原理
在MVC後才推出的架構心法，在web前端很受歡迎，比起MVC更注重於使用者端的介面，把程式拆成三層:介面、資料、與轉換資料層。

* 運作方式
view透過viewModel的資料渲染頁面
當user操作頁面時，view層接收事件給viewModel處理，viewModel呼叫model處理資料
model處理完畢後，呼叫viewModel更新資料
viewModel資料變動，觸發view更新畫面

* <font color="#f00">最主要差異為用資料驅動view的更新，當資料異動時，去更新view</font>

![](https://hackmd.io/_uploads/S1gesj9lT.png)

### PROs
1. 降低學習門檻，更好理解
2. 用binding方式連結view，使viewModel可以不用知道是哪個view，而view自行去更新
3. 商業邏輯不用相依於UI
4. 相對易於unit test, 重用component
### CONs
1. 大型的應用程式中，dataBinding會導致相當大的記憶體消耗
2. 無法簡單暴力的重用 View/ViewController，因為綁定viewModel緣故
3. 並無強硬規定 view 跟 viewModel的關係(ex: 單向影響or雙向綁定)
4. 不易除錯，不容易找出 bug 是在 Model 還是 View

## controller
Controller 是整個運作過程中的核心，掌握與瀏覽器之間的互動行為，也負責收發 Request 與 Response，因此，通常會在 Controller 設置不同的事件 Event，進而觸發不同指令完成後續動作。

例如：當 Controller 收到請求後，Controller 會通知 Model 調度資料，接著再把資料傳遞給 View 來產生樣板，最終將呈現資料的 HTML 頁面回傳到客戶端的瀏覽器。
主要功能:
1.負責監聽和處理用戶的輸入
2.處理業務邏輯
3.路由和控制導航
4.在Model和View之間協調數據的流動以及更新Model和View
![](https://hackmd.io/_uploads/rJGCKj5xT.png)

延伸:RESTful API(用Spring Boot作為範例)
![](https://hackmd.io/_uploads/r11Nf35g6.png)
![](https://hackmd.io/_uploads/r1yLf3qe6.png)

範例:設計一個名為"student"的class的RESTful API
![](https://hackmd.io/_uploads/ryViG3qe6.png)
![](https://hackmd.io/_uploads/ByERz2cxa.png)

Amber


## MVP
### 什麼是MVP
MVP（Model-View-Presenter）是一種用於設計軟件應用程式的軟體架構模式。它主要用於應用程式的用戶界面（UI）層設計，旨在將應用程式的不同部分解耦，以實現更好的可維護性和可測試性。
* Model: 負責資料存取(與資料庫溝通、請求網路資源)。
* View: 負責顯示資料(UI)，並將使用者的操作傳給Presenter。
* Presenter: 負責處理業務邏輯，並負責View與Model的溝通。
![](https://hackmd.io/_uploads/ryE6cicgp.png)
![](https://hackmd.io/_uploads/SkYX6ocxT.png)

### MVP與MVC的差異
* 架構設計：
MVP模型： MVP模型主要強調將應用程序的用戶界面（View）從數據處理邏輯（Model）中分離。Presenter充當View和Model之間的中介，處理用戶界面的邏輯，接受用戶輸入並更新模型。
MVC模型： MVC模型將應用程序分為三個主要部分：Model（數據處理邏輯）、View（用戶界面）和Controller（控制器）。Controller處理用戶輸入，並根據需要更新Model和View。

* 通信方式：
MVP模型： 在MVP中，View和Model之間不直接通信。Presenter充當中介，View和Model只通過Presenter進行間接通信。
MVC模型： 在MVC中，View可以直接觀察Model的變化，或者由Controller通知更新。

* 用戶界面更新：
MVP模型： 在MVP中，Presenter負責控制用戶界面的更新，並根據Model的狀態更新View。
MVC模型： 在MVC中，View可以直接觀察Model的變化，這使得用戶界面的自動更新更容易實現。（比如：觀察者模式）

* 可測試性：
MVP模型： MVP模型通常被認為更容易進行單元測試，因為Presenter和Model之間的通信可以模擬或替換。
MVC模型： MVC模型的Controller通常需要測試用戶界面元素，這可能需要模擬用戶界面事件。

* 用途：
MVP模型： MVP模型通常用於大型應用程序或需要高度可測試性的項目，如桌面應用程序或Android應用程序。
MVC模型： MVC模型在Web應用程序中更常見，例如，MVC框架如Spring MVC用於構建Web應用程序。

* 補充：
MVP與MVC的區別主要在於“C”與“P”的區別以及各自產生的事件流。
在MVP模式中，Presenter只通知View進行展示，View展示邏輯由View自己控制；而在MVC模式中，由Controller控制View的展示邏輯。
MVP為介面導向設計，Presenter與View的通信通過介面；而在MVC模式中，Controller直接操作View。
在MVP模式中，View與Model之間無法進行通信，而在MVC的主動模式中，Model的變化可以直接通知給View。
MVP更有利於單元測試，而MVC組件之間依賴性較強，不利於單元測試。
MVP存在的問題：
Presenter責任過重：相比MVC，MVP模式中Presenter交出View的實現細節控制權，而只負責業務邏輯，但責任依然過重。
業務邏輯不適用：傳統MVP模式中，一個View對應一個Presenter，Presenter中業務邏輯只能為一個View服務，不能複用於多個模塊之間，不同模塊為了實現同樣的業務邏輯，會多次重複操作導致大量冗余代碼。


@Danny
### Model

Model 常譯為「模型」，負責和資料庫溝通。這裡我們要先注意：應用程式和資料庫是兩個不同的東西，在應用程式裡想要做「新增/瀏覽/修改/刪除」的動作，就需要先有 Model 層幫忙去資料庫裡取出必要的資料，把資料放進應用程式裡的某個程式物件，然後才能用 JavaScript 去操作該物件。

這種放資料、與資料庫連動的物件，會被稱為 Model 物件，由 Model 層來統一管理。

![](https://hackmd.io/_uploads/B1Etoocl6.png)


　  　Model 負責封裝所有和商業邏輯有關的資料，例如：資料庫的存取操作、資料結構、資料格式的驗證等等。
　　Model 不需要知道他會如何被顯示或如何被應用，只需專注於資料的存取、定義、驗證即可。
　　Model 層常見的設計技術：Entity Framework, NHibernate, LINQ to SQL, 強行別的 DataSet (Typed DataSet), ADO.NET。

@SEANWEI 
## MVC優缺點

### MVC 的優點
1. 提高程式的可維護性，MVC 將一個功能區分成許多片段，讓程式變得容易維護
2. 在 MVC 中，同一個 Model 可以被不同的 View 重用，提高了程式碼的可重用性
3. MVC 的架構容易識別，可以讓工程師快速掌握項目的結構
4. MVC 將一個功能分成了三部分，因此多個工程師可以同時開發不同部分的程式碼
5. 關注點分離：在個別不同的部分，做各自的事情而互不影響結果。
假設你今天在處理使用者操作介面,那就專心的套版,將Controller傳回來的資料看要怎麼擺放
假設在處理資料流傳入的參數驗證,那就在Controller處理完,不用去管會不會影響到View的呈現
假設是跟資料庫的溝通,就在Model裡將它實作好,不需要擔心是否參數有空值或Null, 因為那些該是在Controller處理掉的。

### MVC 的缺點

1. View 與 Controller 綁住了，不易進行 Unit Test
2. 要花費較多的時間進行前置規劃
3. 要管理較多檔案

## MVC再到前後端分離

首頁的部分就是去 DB 把所有文章都撈回來，然後把資料丟到 view 裡面去 render，搞定！

![](https://hackmd.io/_uploads/rkNdQh5xp.png)

### Client Side Render

![](https://hackmd.io/_uploads/ryyh7n5x6.png)

### SPA

### 前後端MVC

![](https://hackmd.io/_uploads/rJCamh5g6.png)

![](https://hackmd.io/_uploads/HyDkUh9la.png)


## 參考來源

- https://pclevinblog.pixnet.net/blog/post/314562547-%5Bjava_spring%5D%E5%BB%BA%E7%AB%8B%E4%B8%80%E5%80%8B%E5%9F%BA%E6%9C%AC%E7%B0%A1%E5%96%AE%E7%9A%84spring-mvc-project
- https://tw.gitbook.net/spring/spring_web_mvc_framework.html
- https://docs.spring.io/spring-framework/reference/web/webmvc.html
- https://blog.techbridge.cc/2017/09/16/frontend-backend-mvc/
- https://openhome.cc/Gossip/Spring/WebFlux.html