c# mvvm模式获取当前窗口_AWTK-MVVM 介绍
MVVM(Model-View-ViewModel)介紹
8.1 分離用戶界面和業(yè)務(wù)邏輯
在開(kāi)發(fā)應(yīng)用程序時(shí),要把用戶界面和業(yè)務(wù)邏輯分離開(kāi)來(lái),這是每個(gè)程序員都知道的常識(shí)。分離用戶界面和業(yè)務(wù)邏輯有幾個(gè)重要的好處:
8.2 如何分離用戶界面和業(yè)務(wù)邏輯
分離用戶界面和業(yè)務(wù)邏輯,MVVM是目前最常用的模式。MVVM并非憑空出現(xiàn),而是由MVC和MVP一路演化而來(lái)的,每次演化都是為了解決之前沒(méi)有解決的問(wèn)題。
8.2.1 MVC模式
MVC是Model-View-Controller簡(jiǎn)稱,它首次把系統(tǒng)分成Model,View和Controller這三部分,明確的把用戶界面和業(yè)務(wù)邏輯分離開(kāi)來(lái):
- 模型(Model)。簡(jiǎn)單的說(shuō),模型就是業(yè)務(wù)邏輯。我們經(jīng)常說(shuō)面向?qū)ο蟮脑O(shè)計(jì)和建模,所建立的模型就是這里的模型,是對(duì)現(xiàn)實(shí)世界中業(yè)務(wù)邏輯的抽象。面向?qū)ο蟮慕?#xff0c;就是要找到業(yè)務(wù)邏輯中有哪些類以及這些類之間的關(guān)系。類描述了對(duì)象的屬性和行為,類是設(shè)計(jì)時(shí)的概念,對(duì)象是運(yùn)行時(shí)的概念。對(duì)象通常就是業(yè)務(wù)實(shí)體,Model包含一個(gè)或多個(gè)業(yè)務(wù)實(shí)體。很多人(包括國(guó)內(nèi)一些知名的專家)認(rèn)為模型就是數(shù)據(jù),這是沒(méi)有透徹理解面向?qū)ο蟮脑O(shè)計(jì)導(dǎo)致的,對(duì)象是即有數(shù)據(jù)又有行為的,光有數(shù)據(jù)沒(méi)有行為,就無(wú)法讓對(duì)象之間協(xié)作,無(wú)法共同完成業(yè)務(wù)邏輯。
- 視圖(View)。這個(gè)是大家都知道的,就是用戶與軟件交互的界面,對(duì)于GUI應(yīng)用程序來(lái)講,就是窗口和對(duì)話框,以及上面的各種控件。視圖應(yīng)該說(shuō)是為用戶提供了一個(gè)界面,讓用戶可以觀察和操作模型。
- 控制器(Controller)。控制器負(fù)責(zé)解釋來(lái)自用戶通過(guò)鍵盤/鼠標(biāo)等設(shè)備的輸入,并通知模型和視圖做出相應(yīng)的改變。在GUI應(yīng)用程序中,直白的說(shuō),其實(shí)就是控件的事件處理函數(shù),它與界面相關(guān)和模型都相關(guān),它從界面獲取數(shù)據(jù),然后調(diào)用模型的函數(shù),有時(shí)還會(huì)直接更新用戶界面。
8.2.2 MVP模式
MVC模式解決分離用戶界面和業(yè)務(wù)邏輯的問(wèn)題,但是還有一個(gè)重要的問(wèn)題沒(méi)有解決: 控制器是界面相關(guān)的,沒(méi)有辦法為控制器編寫單元測(cè)試程序。為了解決上面的問(wèn)題,MVP模式應(yīng)運(yùn)而生。MVP是Model-View-Presenter簡(jiǎn)稱。
- 模型(Model)。模型還是MVC中的模型,這里不再贅述。
- 視圖(View)。視圖還是MVC中的視圖,但它不需要向模型注冊(cè)改變的事件通知了,這個(gè)由呈現(xiàn)邏輯去做了。
- 呈現(xiàn)邏輯(Presenter)。Controller變成了Presenter只是表面現(xiàn)象,最重要的是MVP對(duì)視圖進(jìn)行了抽象,呈現(xiàn)邏輯不再向控制器那樣直接訪問(wèn)具體的視圖了,而是通過(guò)視圖的接口去訪問(wèn)視圖,視圖的接口是抽象的,可以有不同的實(shí)現(xiàn),所以可以方便的Mock出一個(gè)視圖,讓編寫呈現(xiàn)邏輯的單元測(cè)試程序成為可能。注意,這里視圖的接口并不是通用的,每個(gè)視圖都有一個(gè)獨(dú)立的接口,有一個(gè)真正的實(shí)現(xiàn)和一個(gè)用于測(cè)試Mock的實(shí)現(xiàn)。
從理論上講,MVP模式已經(jīng)很完備了,它很好的分離的界面和實(shí)現(xiàn),也可以為呈現(xiàn)邏輯編寫單元測(cè)試程序了。但是從工程角度來(lái)看,MVP卻有一個(gè)非常致命的缺陷:要編寫大量無(wú)聊的代碼!
為了方便說(shuō)明,我們以一個(gè)編輯圖書(shū)信息例子,看看要寫哪些無(wú)聊的代碼。這個(gè)例子非常簡(jiǎn)單,卻要寫不少無(wú)聊的代碼:
- 1.初始化的時(shí)候,要為控件注冊(cè)事件處理函數(shù),比如為『保存』按鈕注冊(cè)事件處理函數(shù)。
- 2.初始化的時(shí)候,要把圖書(shū)信息,如書(shū)名、作者和出版社等信息從模型中取出來(lái),一個(gè)一個(gè)的設(shè)置到視圖的控件中去,在這個(gè)過(guò)程中,可能需要對(duì)數(shù)據(jù)格式進(jìn)行轉(zhuǎn)換,比如出版日期,在模型中是一個(gè)整數(shù),在視圖上表現(xiàn)為一個(gè)字符串,這就需要轉(zhuǎn)換。
- 3.在編輯結(jié)束時(shí),要從視圖中把圖書(shū)信息,如書(shū)名、作者和出版社等信息一個(gè)一個(gè)的取出來(lái),再保存到模型中去。在這個(gè)過(guò)程中,可能需要對(duì)數(shù)據(jù)格式進(jìn)行轉(zhuǎn)換,比如前面的出版日期,要把視圖中的字符串轉(zhuǎn)換回模型中的整數(shù)。
- 4.View都有一個(gè)接口定義,有一個(gè)真正的實(shí)現(xiàn)和一個(gè)Mock的實(shí)現(xiàn)。
這些代碼很簡(jiǎn)單卻很無(wú)聊,在每個(gè)有界面的模塊中,都遵循同樣的規(guī)律,卻又完全不同,不得不重新編寫。
8.2.3.MVVM模式
把MVP模式這些規(guī)律找出來(lái)進(jìn)行抽象,通過(guò)一些規(guī)則在視圖和模型建立聯(lián)系,也就是數(shù)據(jù)綁定和命令綁定,就形成了MVVM模式。MVVM是Model-View-ViewModel簡(jiǎn)稱。在MVVM中:
- 模型(Model)。模型還是MVC中的模型,這里不再贅述。
- 視圖(View)。視圖還是MVC中的視圖,但它不需要向模型注冊(cè)改變的事件通知了,這個(gè)由數(shù)據(jù)綁定去做了。
- 視圖模型(ViewModel)。 ViewModel不是Controller也不是Presenter,視圖模型是視圖還是模型?按MVVM的發(fā)明者John Gossman的話說(shuō),視圖模型是視圖眼中的模型。放大鏡下的蟲(chóng)子還是蟲(chóng)子,所以視圖眼中的模型還是模型。視圖模型與視圖沒(méi)有直接關(guān)系,是可以為之編寫單元測(cè)試的。
MVVM模式有下列好處:
- 強(qiáng)制分離用戶界面和業(yè)務(wù)邏輯。在MVC和MVP中,不能強(qiáng)制分離用戶界面和業(yè)務(wù)邏輯,程序員的一念之間,就導(dǎo)致用戶界面和業(yè)務(wù)邏輯混在一起。MVVM中不需要編寫界面相關(guān)的代碼,自然沒(méi)有辦法讓用戶界面和業(yè)務(wù)邏輯耦合到一起。
- 界面描述文件和程序代碼之間具有更松的耦合。通常用XML或RC文件來(lái)描述界面,在MVC和MVP中,在界面上增加一個(gè)控件或刪除一個(gè)控件,都會(huì)導(dǎo)致相應(yīng)的代碼需要修改。而在MVVM中,采用了面向意圖的編程,界面上表現(xiàn)的只是一種意圖,至于在程序中,誰(shuí)去實(shí)現(xiàn),怎么實(shí)現(xiàn),甚至有沒(méi)有實(shí)現(xiàn),界面都是不關(guān)心的,所以界面和代碼之間值的耦合是很松的。
- 不需要學(xué)習(xí)GUI的API。通過(guò)數(shù)據(jù)綁定和命令綁定建立視圖和模型之間的聯(lián)系。用聲明式的規(guī)則取代命令式的代碼,不需要寫界面相關(guān)的代碼,所以不需要學(xué)習(xí)GUI的API,無(wú)論是采用Qt還是AWTK,都用同樣的方式開(kāi)發(fā)。
視圖模型和模型并不相同,之所以要引入視圖模型,主要原因有:
- 模型中的數(shù)據(jù)有時(shí)并不適合直接顯示在視圖上。比如出版日期,在模型中是整數(shù),直接顯示出來(lái),用戶就看不懂,需要轉(zhuǎn)換成人類可以理解的字符串。
- 模型中的一個(gè)數(shù)據(jù)項(xiàng)可能以多種形式呈現(xiàn)在視圖上。比如出版日期,除了顯示出版日期外,也可能把最近出版的書(shū),顯示一個(gè)新書(shū)標(biāo)志。
- 視圖中的輸入數(shù)據(jù)和模型中的存儲(chǔ)數(shù)據(jù),它們的格式有時(shí)可能不同。比如出版日期,視圖上輸入的格式和模型里存儲(chǔ)的格式就不一樣。
- 視圖需要視圖模型提供數(shù)據(jù)校驗(yàn)規(guī)則來(lái)判斷視圖上的輸入是否合法。
- 有些數(shù)據(jù)是有依賴關(guān)系的。比如在輸入收貨地址時(shí),選擇省份時(shí),城市列表跟著變化。
- 有些狀態(tài)不屬于業(yè)務(wù)邏輯,但是需要保存下來(lái)。如為了支持撤銷操作,需要保存命令歷史記錄。
- 在C/C++等靜態(tài)語(yǔ)言中,沒(méi)有辦法通過(guò)函數(shù)的名稱去調(diào)用對(duì)象的成員函數(shù),也沒(méi)有辦法通過(guò)屬性的名稱去訪問(wèn)對(duì)象的成員變量。視圖模型需要提供一種機(jī)制來(lái)實(shí)現(xiàn)這些功能,否則綁定規(guī)則就沒(méi)法實(shí)現(xiàn)。
MVVM 的缺點(diǎn)。
- 內(nèi)存問(wèn)題。據(jù)說(shuō)WPF內(nèi)存開(kāi)銷很大,即使在PC上也大得讓人無(wú)法忍受(常有人借此來(lái)反對(duì)MVVM)。WEB前端流行的MVVM框架,像React和Vue.js等,采用虛擬DOM的方式,內(nèi)存需求可能有大幅度增加。
- 性能問(wèn)題。MVVM通常的做法是,模型有變化時(shí)會(huì)刷新整個(gè)界面。如果采用虛擬DOM的方式,還需要重新構(gòu)建一個(gè)虛擬DOM,與原來(lái)的虛擬DOM比較,性能開(kāi)銷就更大了。
- 調(diào)試問(wèn)題。如果沒(méi)有工具的協(xié)助,數(shù)據(jù)綁定會(huì)讓調(diào)試變得困難。
以上這些問(wèn)題在手機(jī)和PC上,已經(jīng)不是什么大問(wèn)題了,但對(duì)于嵌入式系統(tǒng)來(lái)說(shuō),仍然是難以跨越的障礙,所以目前幾乎沒(méi)有針對(duì)嵌入式平臺(tái)開(kāi)發(fā)的MVVM框架。
8.3 AWTK-MVVM
AWTK-MVVM是一套用C語(yǔ)言開(kāi)發(fā)的,專門為嵌入式平臺(tái)優(yōu)化的MVVM框架。它實(shí)現(xiàn)了數(shù)據(jù)綁定、命令綁定和窗口導(dǎo)航等基本功能,使用AWTK-MVVM開(kāi)發(fā)應(yīng)用程序,無(wú)需學(xué)習(xí)AWTK本身的API,只需學(xué)習(xí)綁定規(guī)則和模型的實(shí)現(xiàn)方式即可。
與其它MVVM框架相比,AWTK-MVVM特點(diǎn)有:
- 代碼小。
- 核心代碼:約3000行。
- AWTK相關(guān)代碼:約700行。
- jerryscript相關(guān)代碼(可選):約1700行。
- 性能高。核心代碼用C語(yǔ)言開(kāi)發(fā),其性能與直接使用AWTK差別不大。
- 內(nèi)存開(kāi)銷小。
- 一條綁定規(guī)則大概需要150字節(jié)。一個(gè)窗口上若有10條綁定規(guī)則,內(nèi)存占用了也就1.5K。
- 列表中的綁定規(guī)則可以共享,額外增加的內(nèi)存開(kāi)銷,比例也是很小的。
- 隔離更徹底。在AWTK-MVVM中,界面和綁定規(guī)則在XML中描述,開(kāi)發(fā)應(yīng)用程序時(shí)只需要開(kāi)發(fā)模型(也就是業(yè)務(wù)邏輯)即可。除非通過(guò)特殊手段,開(kāi)發(fā)者沒(méi)有機(jī)會(huì)直接去訪問(wèn)視圖。
- 易調(diào)試。
- 提供視圖模型的框架生成工具,避免手寫代碼造成的錯(cuò)誤。
- 增加了各種異常處理的LOG信息。
- 提供大量的demo以供參考。
- 開(kāi)放源碼,調(diào)試方便。
- 支持多語(yǔ)言開(kāi)發(fā)。
- 目前支持C語(yǔ)言和JS。
- 以后會(huì)根據(jù)需要支持新的編程語(yǔ)言。
- 可移植到其它GUI。AWTK-MVVM是為AWTK設(shè)計(jì)的,但是我們隔離了與AWTK相關(guān)的代碼,讓它可以移植到其它GUI。AWTK相關(guān)的代碼僅僅700來(lái)行,可見(jiàn)移植到新的GUI是非常容易的事情。當(dāng)然,AWTK可以滿足常見(jiàn)的需要,這樣做只是給開(kāi)發(fā)者提供更多選擇。
AWTK-MVVM也有些限制,目前不支持界面元素動(dòng)態(tài)生成,這時(shí)可以結(jié)合傳統(tǒng)的方法開(kāi)發(fā)。以后AWTK會(huì)支持WEB前端流行的框架如Reactjs和Vuejs,在高端平臺(tái)(如手機(jī)、小程序和桌面程序)中應(yīng)用。
在后面的章節(jié)中,我們將詳細(xì)介紹AWTK-MVVM的具體用法。
總結(jié)
以上是生活随笔為你收集整理的c# mvvm模式获取当前窗口_AWTK-MVVM 介绍的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: qos的_QoS 概述
- 下一篇: java emoji显示乱码_Java