標籤:

MVVM模式中處理業務邏輯是應該在M中還是VM中?

比如要通過網路監聽獲取數據更新並顯示到界面中。是應該用M來獲取數據並在VM中定期檢查更新;還是應該用VM來獲取數據,然後同時更新V和M。


業務邏輯是應該放在 M層

但是按照目前比較流行的模型來看, 能夠在VM中訪問的M都是DTO 也就是貧血的Model數據

業務邏輯都是包裝在 Service 層 也就是一般所說的 BusinessLayer. 這樣無論本地的業務還是遠程業務都可以比較方便的調用。

View-&>VM--&> Services 這樣的結構

Service Contract +DTO 基本上就是 MVVM相對的M層了


去年暑假實習一直在做MVVM的開發。就我所知所有的後端和業務邏輯都應該是在M端的,寫界面XAML是V端,前後端之間可以互不干擾完成設計/開發,最後再加一個VM,而VM做的事就是銜接V和M。Wiki上這一段很清楚地解釋了view model的作用,也就是把model中的數據對象轉換成view可以直接使用的形式(比如string或者collection等等)。

MVVM facilitates a separation of the development of the graphical user interface (either as markup language or GUI code) from the development of the business logic or back-end logic (the data model). The view model of MVVM is a value converter;[3] this means that the view model is responsible for exposing the data objects from the model in such a way that the objects are easily managed and consumed. In this respect, the view model is more model than view, and handles most if not all of the view』s display logic.

你提到的兩種方案,第二種「用VM獲取數據」肯定是不對的,違反了MVVM的基本邏輯(即把前後短清晰分開,用VM作為連接橋樑)。第一種是用M獲取數據沒錯,但我沒使用過你所謂的「定期檢查更新」。做完data binding以後在VM的每個property里加上OnPropertyChanged,每次這個property被set了新的值(比如model里更新了這個值),view里綁定此property的地方都會自動被更新,不需要你手動把這個更新發給view。

建議你用OnPropertyChanged作為關鍵詞搜個例子,很好懂。關鍵是要理解MVVM的內在邏輯、把它的優點最大化,不要繼續用MVC的方式想問題。


寫一個獲取數據的service,在view model里調用,來更新model


要談MVVM,我想是不能繞開MVC的。

MVC的出現是隨著代碼規模的上升而粗現的,問MVVM,我想題主對MVC已經有一定的了解了,MVC的前世今生就不展開了。

直接來看一個比較有代表性的MVC,如下圖所示(因為職業的關係,圖片來自apple開發者文檔,不過大同小異):

Model負責數據的處理,View負責視圖的顯示以及需要的監視,Controller用於流程式控制制。

基本的思想是:

View(界面)觸發事件 –&> Controller(業務)處理了業務,然後觸發了數據更新;

或者

不知道誰更新了Model的數據–》Model(帶著數據)通知View–》View更新數據。

邏輯清晰。

MVC帶來了功能的獨立,以及Model的復用,但三方依然是互相引用的,所以一個改進版的可能是這樣(圖片同樣來自apple開發者文檔)

這裡的差別主要是取消了View和Model的耦合,Model發生變化時通知controller,由controller來更新view。

在這兩種裡面,在理想上設計的很美好,優點一大堆,在實際中,卻有幾個不盡如人意的地方,其中最大的問題,在於Controller的臃腫:

負責View的布局、載入、展示順序,

View的logic,

要負責連接View和Model,

負責多種事件響應

。。。。。

目前為止,我見過的最多的Controller類,有超過6k行代碼,裡面的功能過多,調來調去,牽一髮而動全身,測試和維護極為困難。

除此之外,有些邏輯,諸如網路請求、數據校驗這樣的logic放在Controller還是Model中,似乎在不同的代碼中有著不同的答案。

在我看來,MVVM就是為了解決這兩個問題,Controller的高度臃腫和logic位置的模稜兩可。

一個典型的MVVM如下圖所示(自己畫的,湊合看看):

這裡多出來了一個ViewModel,那代碼多出來多少呢?

很少。

由於View和Controller終於正式在一起了,這個ViewModel就是MVC的Controller中除了view展示和事件響應之外的諸如業務邏輯、網路請求、合法性校驗這些代碼組成的,這些代碼本來就是要寫的。正因為如此,從MVC切到MVVM像 @winter大神說的,M層是不用動的喲。

說白了,這是Model層對Controller層的適配器,Controller調用Model、發起網路請求、從Model取出的字元串要本地化、檢查View中輸入的Email是否合法等等這些,全部放在VM(ViewModel)中。題主的問題,也就有答案了吧。

至於MVVM的好處,一是Controller的瘦身,二是ViewModel的復用和良好的可測試性,這些代碼能復用真實爽歪歪了,第三是一個隱藏屬性,如果你使用響應式編程的話,代碼量會明顯減少(在iOS上使用ReactiveCocoa和MVVM,代碼量可以減少30%左右)。

歡迎指正。


你沒有說明是後端還是前端

我寫的avalon是一個前端MVVM框架,它能在視圖中綁定事件,攔截器,過濾器,這些都不是表示狀態或數據的東西,它們與業務邏輯緊密相關.

視圖層 V,展現數據,綁定事件,

視圖模型層 VM, 從數據模型層變換而來, 除了數據或狀態flag,還有許多事件回調,$watch回調(當某個數據變動時會執行的函數), widget的配置對象

模型層 M, 這是通過AJAX請求得到,或者通過後端輸出時就列印在頁面某個script標籤內, 都是數據(JSON),沒有函數

業務邏輯層 BS,這不歸為MVVM之內,但它們應該使用類進行組織,在VM中的某個函數裡面被調用。

迷你易用的MVVM框架

Avalon中文社區


這個時候不應該是mvvm了,應該是mvvmc


作為一個菜鳥,我也來湊熱鬧了.

首先我也不知道自己的理解是否正確,所以過來找罵的.

入正文

在知乎回答就一定跑題,所以先談mvc.

我最討厭別人談mvc時把那個圖擺出來,對就這個

我也不知道這是哪來的圖,聽說是經典MVC,但你也知道沒有幾個框架是完全按這樣寫的。

作為後端,最熟悉的模式是這樣的

(圖中View與Model是有小虛線,但是後端開發中我根本沒見過,所以被我塗掉了)

看起來有點像MVP,但MVP是從V開始的,即用戶在V觸發事件-&>P-&>M,再傳回M-&>P-&>V。

而這張圖,面向HTTP請求,是從C開始的(具體流程看圖),這個版本MVC也叫Model2

你會發現有好多種MVC,好多版本的圖,所以關於MVC我不想講那麼細。

MVC用來幹嘛的?換種說法,設計模式/架構模式用來幹嘛的?

解耦,提高復用,應對變化,~~裝逼?~~

可以簡單地說MVC是用來解耦的,讓View負責展示,讓Model負責業務邏輯,業務邏輯與視圖分離

僅此而已

那麼回到mvvm,作為mvc的衍生品,它也是要做到視圖與邏輯分離,所以業務邏輯還是乖乖地待在M,展示讓V負責,VM負責從M拿數據綁定到V(因為這是一件麻煩事,所以專門搞了個VM)

那麼Controller去哪了?在Model2中Controller站在View與Model的前面負責選擇合適的Model處理業務,選擇合適的View生成頁面。現在mvvm中站在前面的是View,負責選擇Model的是ViewModel,所以沒Controller的事了。Model我的想法跟第一名的一樣,就是請求後端的東東,這裡Model的作用跟上圖一樣作為業務層和持久層的入口

其他廢話

拿vue舉例,有的人認為new Vue({data:...}) 這裡的data是model,也有的人說,在前端,model就是存數據的,我不知道怎麼回答,因為我是菜雞

關於vm,我認為v負責展示vm的數據,v中的點擊事件也是寫在vm中的,在這裡我把點擊事件處理函數也看做一種數據

但奇怪的是vue中,vm類似一種數據綁定器的存在,我不知道怎麼回答,因為我是只菜逼

mvvm中 viewmodel該如何設計?


我們目前做的android項目是這樣處理的:

m層:數據處理(拿到網路或其他地方獲取到的數據 處理好傳遞給mv)

mv層:從m層獲取到處理好的數據,通知v層進行UI的更新;接收V層的請求數據事件,去m層獲取數據;充當一個橋樑角色

v層:UI事件的監聽(通知mv層去m層獲取數據),UI界面的顯示

m層里主要是只關注了數據相關的處理邏輯,而mv層應該進行業務邏輯的編寫(諸如進行登錄,密碼驗證等工作),如果業務邏輯較複雜,可以單獨在進行細化,比如加一個邏輯層,這樣減少了mv層的負擔,也便於業務的復用;簡單的可以直接放到mv層。


MVVM和MVC中的M都是泛指 service+dto+entity+repository 等這一系列的層次關係的組合,完全的使用這種模式就可以不存在什麼業務層持久層等,只是由於實際需要M往往需要進行分割以滿足整個項目的架構需要,所以現有的MVVM實現大多是指在表現層實現VVM,VM調用service,傳遞的dto,vm也是中沒有業務的,整個項目一般也是不存在單獨的m層的,因為從定義上他是一種泛指的層


The MVVM Pattern

MS給的解釋:

Model:

The model in MVVM is an implementation of the applications domain model that includes a data model along with business and validation logic. Examples of model objects include repositories, business objects, data transfer objects (DTOs), Plain Old CLR Objects (POCOs), and generated entity and proxy objects.

ViewModel:

The view model acts as an intermediary between the view and the model, and is responsible for handling the view logic. Typically, the view model interacts with the model by invoking methods in the model classes


最早接觸mvvm是再做wpf的時候,那個時候我的老大就說 mvvm是基於mvc的思想 所以邏輯部分還應該是在c


可以寫一個專門的監聽器,用來監聽並獲取數據,將數據轉為model,vm使用這個監聽器。設計模式沒有固定的方法,得看需求,我個人一般是model相關的業務邏輯放到model,其它複雜的業務邏輯單獨做成service或叫helper,有時很簡單的業務邏輯直接放在vm。


推薦閱讀:

Vue.js會一直維護嗎?
vuejs ui庫優劣勢分析和選擇?
KnockoutJs怎麼樣?
主流的MVVM框架中如何做國際化?
在開發過程中如何應用mvvm思想(非現有的框架)?

TAG:MVVM |