# MVVM (Model-View-ViewModel) ![MVVM](https://i.imgur.com/UBcyNz4.png) MVVM(<font color=#0088FF>Model</font>-<font color=orange>View</font>-<font color=#00CC00>ViewModel</font>) - 是一種軟體架構模式 - 也被稱為 model-view-binder ,與 - MVP(<font color=#0088FF>Model</font>-<font color=orange>View</font>-<font color=#00CC00>Presenter</font>) - PM(Presentation Model) 一樣都來自 MVC(<font color=#0088FF>Model</font>-<font color=orange>View</font>-<font color=#00CC00>Controller</font>) 模式 ## 架構: Model: - 管理所有的**資料來源**(ex. API、資料庫) - 管理後端的**業務邏輯處理**和**數據操控(CRUD)** View: - 在螢幕上 **顯示介面(UI)** 給使用者 - 接收**使用者與介面的互動( User Interaction )** :::warning - 前端主要由 HTML 和 CSS 來構建 - 通常是應用程序中的一個頁面,也可以是父視圖的子組件 ::: View Model: - 負責處理 **<font color=orange>View</font> 的畫面邏輯/UI邏輯**(ex.事件處理、元件的互動/指令) - 接收 **<font color=orange>View</font> 的指令(ICommand)** - 並**對 <font color=#0088FF>Model</font> 請求資料**(ex.Ajax...method of Model Classes) - 將 <font color=orange>View</font> 所需的**資料 保存/暫存**(輸入/顯示) 起來供 <font color=orange>View</font> 使用 :::success - 前端主要由 JavaScript 來構建 - <font color=#00CC00>View Model</font> 為 <font color=orange>View</font> 與 <font color=#0088FF>Model</font> 的中介,也是 MVVM 的核心 - <font color=orange>View</font> 所使用的不是 <font color=#0088FF>Model</font> 的數據,而是 <font color=#00CC00>ViewModel</font> 的數據,由 <font color=#00CC00>ViewModel</font> 負責與 <font color=#0088FF>Model</font> 交流互動,這就完全解耦了 <font color=orange>View</font> 和 <font color=#0088FF>Model</font> ,這是以 **技術單位**-前後端 **關注點分離(Separation of Concerns , SoC)** 方案實施的重要一環。 ::: ## MVVM原理: - 利用 **Data Binding (Library)** 來實現 **Observer Pattern** 的概念 - 由 <font color=orange>View</font> 來訂閱(subscribe) 在 <font color=#00CC00>ViewModel</font> 中所需要的資料 - 並在**資料異動**時才更新 UI ( <font color=orange>View</font> ) - <font color=#00CC00>ViewModel</font> 使用 **ICommand介面** ,接收 <font color=orange>View</font> 的觸發,利用 - **[ 命令(ICommand)繫結、調用 <font color=#00CC00>ViewModel</font> 的 method ]** - **[ 調用 <font color=#0088FF>Model</font> classes 的 method ]** 分離 **<font color=#EEDD00>UI邏輯</font>** 與 **<font color=#715CA8>業務邏輯</font>** - <font color=#00CC00>ViewModel</font> 使用 **INotifyPropertyChanged 屬性更改通知** - 通知結繫端( <font color=orange>View</font> ),物件的屬性內容( <font color=#00CC00>ViewModel</font> )發生變更 - 當結繫端( <font color=orange>View</font> )收到此通知便會進行 畫面(UI) 更新的動作 即 **資料驅動(Data-Driven)** 而不是 事件驅動(Event-Driven) :::danger - 但是**過大資料繫結**會導致相當大的**記憶體消耗** ::: ## 與 MVC 的差別 核心的運作: - <font color=#00CC00>ViewModel</font> 在繫結到 <font color=orange>View</font> 後,基本 上**不接收使用者的行為( User Interaction )**,而是使用 **命令(Command)** 來控制 - <font color=#00CC00>Controller</font> 包含 **接收使用者的行為( User Interaction )** 和 資料 Model 上的改變 畫面的更新: - MVVM 的 <font color=orange>View</font> 使用 **Data Binding** 訂閱 <font color=#00CC00>ViewModel</font> 的 屬性更改通知 - MVC 的 <font color=orange>View</font> 監聽 <font color=#0088FF>Model</font> 的資料改變,同時也可能包括 Ajax 請求操作 >[【乾貨理解】理解javascript中實現MVC的原理](https://iter01.com/74230.html) ## 與 MVP 的差別 - 當 MVVM 的 <font color=#00CC00>ViewModel</font> 資料更新時,透過 **INotifyPropertyChanged 屬性更改通知**,來通知 <font color=orange>View</font> 更新 - 當 MVP 的 <font color=#0088FF>Model</font> 資料更新時,使用 **事件(Event)** 或是 **回呼函式(callback Function)** 給 <font color=#00CC00>Presenter</font> ,再由 <font color=#00CC00>Presenter</font> Call <font color=orange>View</font> 的更新 Function > [MVP (Model View Presenter) 設計模式](http://programer-learn.blogspot.com/2014/09/mvp-model-view-presenter.html) ## MVVM流程: - 當使用者跟 <font color=orange>View</font>(UI) 互動後,將命令傳給 <font color=#00CC00>ViewModel</font> 處理 - <font color=#00CC00>ViewModel</font> 接收 <font color=orange>View</font> 的命令並對 <font color=#0088FF>Model</font> 請求資料 - <font color=#00CC00>ViewModel</font> 收到 <font color=#0088FF>Model</font> 的資料後,做資料的暫存,或是處理成 <font color=orange>View</font> 所需要的格式 - <font color=#00CC00>ViewModel</font> 通知 <font color=orange>View</font> 資料變更 - <font color=orange>View</font> 更新畫面 ## MVVM優劣: - 開發人員和設計人員可以更加獨立於各自的領域,達到關注點分離(Separation of Concerns) - 開發人員可以專注於 <font color=#00CC00>ViewModel</font> 、 <font color=#0088FF>Model</font> ,可以在不使用 <font color=orange>View</font> 的情況下為 <font color=#00CC00>ViewModel</font> 和 <font color=#0088FF>Model</font> 創建**單元測試** - 設計人員可以專注於 <font color=orange>View</font> 的 **UI** 與 <font color=#00CC00>ViewModel</font> **UI邏輯**,也可以在 <font color=#00CC00>ViewModel</font> 輕鬆生成 <font color=orange>View</font> 所需要的**範例數據**以進行處理 <br><br><br><br><br> 參考如下: > [程式設計師應該知道的MVC,MVP,MVVM設計模式區別及優缺點 ](https://kknews.cc/zh-tw/news/8qzkmog.html) > [MVP(SC)、MVP(PV)、PM、MVVM 和 MVC 表現模式架構對比](https://developer.aliyun.com/article/380256) > [Binding ICommand (命令繫結)](https://me1237guy.pixnet.net/blog/post/67837890) > [邏輯移到ViewModel](https://skychang.github.io/2011/12/31/WPF-%E2%80%93-MVVM-%E4%B8%89/#:~:text=%E4%BA%86%E7%94%9A%E9%BA%BC%E8%AE%8A%E5%8C%96%E3%80%82-,%E9%82%8F%E8%BC%AF%E7%A7%BB%E5%88%B0ViewModel,-%E5%88%B0%E9%80%99%E9%82%8A%EF%BC%8C%E6%88%91) > [WPF 的 MVVM 測試](http://radio-idea.blogspot.com/2018/12/wpf-mvvm.html) > [The MVVM Pattern](https://docs.microsoft.com/en-us/previous-versions/msp-n-p/hh848246(v=pandp.10)?redirectedfrom=MSDN) > [MVVM架構](https://ithelp.ithome.com.tw/articles/10192829) > [MVVM模式](https://www.twblogs.net/a/5b8395d32b71776c51e3b1de) ###### tags: `設計模式`