架構模式之MVVM
架構模式之MVVM
前言
MVVM是一種架構模式,本文會涉及一小點vue程式碼,以及一篇簡單的springboot的程式碼,建議在閱讀本文件前先對這兩門技術做一些學習。
什麼是MVVM
MVVM是三個單詞的簡稱,分別是Model,View和ViewModel。
在闡述MVVM的概念之前,讓我們先看下這麼多年js的發展階段。
第一階段,使用原生的js直接操作DOM節點。
var dom = document.getElementById('name');
dom.innerHTML = 'HelloWorld!';
第二階段,原生API並不是那麼的易用,還要考慮瀏覽器的相容性,於是Jquery出現了。
$('#name').text('Homer').css('color', 'red');
第三階段,MVC模式
這個時候就需要服務端應用來配合開發了,用js來根據伺服器傳送過來的資料進行渲染。
現在,前端頁面越來越複雜,使用者的互動性操作也越來越多,要求也越來越高,僅僅是使用Jquery已經滿足不了前端的需求了,於是MVVM模型出現了。
MVVM借鑑了MVC的思想,在前端頁面中,View用於專門的顯示,而裡面的資料用Model來進行渲染,這樣兩者就做到了很大程度的分離。
而ViewModel就是用於把Model和View關聯起來,Model的資料同步到View顯示出來,把View的修改同步回Model,做到這兩件事的就是ViewModel。
而這種操作也被稱為“雙向繫結”。
雖然我們也可以用jquery甚至用原生js來實現MVVM,但Vue自己已經包含了這個功能以及主打的就是它(雙向繫結)。
因此Vue基本是MVVM的代言者(個人看法)。
而MVVM的特點也展現出來了。
MVVM的特點
1. 低耦合性。
View可以獨立於Model變化和修改,一個ViewModel可以繫結到不同的View上,當View變化的時候Model不可以不變,當Model變化的時候View也可以不變。
2. 可重用性。
把一些檢視邏輯放在一個ViewModel裡面,讓很多View重用這段檢視邏輯,也就是元件化思想。
3. 獨立開發。
開發人員可以專注於業務邏輯和資料的開發(ViewModel),設計人員可以專注於頁面設計。
MVVM的組成
組成已經在剛剛的對MVVM的介紹中已經說明的很明白了,轉換成更直觀一些的圖就是上面這張。
Model的資料利用ViewModel同步到View顯示出來,把View的修改利用ViewModel同步回Model。
View
介面和顯示,通常由HTML組成,可以使用各種UI框架組成頁面,例如element,不直接與Model互動。
ViewModel
包括介面邏輯和模型資料封裝 ,事件響應,繫結的屬性等,是View和Model的橋樑
Model
資料核心,連線著ViewModel。
MVVM與MVC
MVC和MVVM的區別其實已經討論過了,MVVM就是借鑑的MVC的思想,MVC的概念可以去參考另一篇文件。
MVC出現的時候前端還並不是很成熟,很多業務邏輯在後臺實現即可,因此當時前端甚至還沒有MVC這個概念,MVC的目的就是將Modle和Controller分離,也就是單向通訊,而MVVM則是將邏輯重點在前端實現,利用ViewModel進行雙向繫結。
MVVM的實現
首先建立一個Helloworld級的html頁面,在這裡我們使用Vue來感受下MVVM。
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
HelloWorld!
</div>
</body>
<script>
</script>
</html>
建立一個Vue物件
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
HelloWorld!
</div>
</body>
<script>
var app = new Vue({
})
</script>
</html>
這時我們想要使用MVVM思想進行開發,那麼就要分別創建出View和Model。
<body>
<div id="app">
{{message}}
</div>
</body>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello World!'
}
})
</script>
在這篇短小的程式碼中,{{message}}代表的就是View,而它則是利用了ViewModel繫結上了在Vue物件中的message變數也就是Model,這就是通過Vue來進行MVVM開發,我們嘗試提供給使用者一個通道能直接改變Model,看看View會發生生麼。
<body>
<div id="app">
{{message}}</br>
<button @click="add">+1個感嘆號吧</button>
</div>
</body>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello World!'
},
methods : {
add : function(){
this.message = this.message+"!"
}
}
})
</script>
測試下點選這個按鈕會發生什麼,
感嘆號變成了兩個!
讓我們根據前面的理論知識來思考下發生了什麼,按鈕繫結的是methods裡面的add方法,在add方法中,我們使代表著Model的變數message的末尾加入了一個感嘆號。
Model的變化令ViewModel更新了與Model繫結的View,而此時與Model繫結的View就是{{message}}。
應用場景
首先,我們是不考慮後端模板的,後端模板不利於前後端分離,這是不可爭的公認事實,這就不在此處進行討論說明了。
但如果一些需求需要由前端非同步完成,並且是使用者修改UI的情況下,我們就需要先儲存一份現階段UI,然後去後臺請求完成之後在展示上需要與後端同步,甚至需要用jquery來直接操作dom。
那麼MVVM雙向繫結呢,我們只需要修改資料Model,因為Model和View是已經繫結好的,因此我們不用在意View怎麼樣,因為我們在Model改變的時候View就已經改變了。
它的優點
1.雙向繫結技術,這是MVVM思想主打的思想,也是它的最優點
2.View可以將後端控制器大量處理的業務放在自己這裡,雖然view幹了不屬於它職責範圍內的事,但卻將後端控制器大量瘦身了。
3.可以對View的資料處理部分抽象出來一個函式處理model,組成一個功能元件,多次使用。
也總會有不足之處
MVVM確實解決了現階段前端開發的很多問題,但再厲害的技術,也總會有些許不足。
1.資料繫結使得 Bug 很難被除錯。介面出現了異常,有可能是View的程式碼有問題,也可能是Model。
2.Model長期持有,不釋放記憶體,就造成了花費更多的記憶體