WPF_MVVM 開發的幾種模式討論
在WPF系(包括SL,WP或者Win8)應用開發中,MVVM是個老生常談的問題。初學者可能不會有感覺,但當你寫一個核心邏輯能在各種平臺上無縫移植,而只需改改UI的時候,那種快感是無法用語言來形容的。
筆者當初接觸時,對MVVM並不以為然,編了很多程式碼以後,反過來看MVVM for WPF的經典文章以後,才若有頓悟。標準的MVVM把程式分成了Model, ViewModel和 View三個部分,但方法是死的,人是活的。我一般的做法是邏輯寫一個,View寫一個,沒有那麼嚴格。為了方便討論,我們把ViewModel和Model合稱Model, View還是View, 分別代表邏輯和介面。分離是肯定的,可是在程式中終究是要把View和Model在某個地方結合起來。 本文就討論下幾種結合的方式。
1. 標準MVVM(由View例項化Model)
標準的MVVM,做法當然是先設計Model, 然後再設計View, 在View的程式碼裡有且僅有這麼幾句話:
public partial class PluginMangerUI : UserControl { public PluginMangerUI() { this.InitializeComponent(); PluginManager manager = new PluginManager(); this.DataContext = manager; } }
基本的邏輯結構可以用下圖來表示。不同的庫是由自底向上的方式設計的。
這種由View呼叫Model, 並具體由View負責Model例項化的方式是最為普遍的,非常適合於需要跨平臺的應用。當然,Model並不知道View的存在,因此View要承擔所有的介面邏輯,好在WPF已經給出了足夠多的解決方案,觸發器,模板。基本絕大多數需求都能滿足。
2. 外掛結構(Model例項化View)
這種做法,是筆者經常用的。在Model裡,通過以下程式碼來實現介面生成
internal class ViewExample : UserControl { } public class ModelExample : IView { private readonly ViewExample view; public ModelExample() { this.view = new ViewExample(); } public object UserControl { get { return this.view; } }
肯定會有同學問道,怎麼會有這麼奇怪的寫法?這種做法的最常見場合應該是外掛系統。一個個的Model其實是一個個的外掛,它們應該具備自治性。因此,應該由自身負責介面的產生。
它的好處是可以通過Model更加精細的調節View的行為,你可以在任何時候獲得View內部ListBox的SelectIndex, 而不用麻煩的用Binding。 打個比方說,遊戲開發中,你需要隨時控制物體的運動速度和方向,這樣Model就必須控制View. 繫結很難解決這類問題。
我不知道有多少同學在WPF中使用外掛的設計思想。若按外掛的思路,庫應該按功能劃分。在這種設計思路下,不同的庫便不是自下而上的分層了,而是通過領域和功能分層,如下圖:
每一個功能庫都有完整的自治性,當你將該功能庫拷貝到主框架之下時,它就會自動載入,由Model負責View的生成。一切合情合理。
3. 組裝車間(第三方組裝View和Model)
這種思路來自於工廠方法,類似於裝配車間,View和Model都不負責互相的例項化。而有一個“管理器”負責組裝它們。這樣的好處在於可配置。你可以通過配置檔案動態的改變View.
我記得一種比較著名的WPF嚮導(Wizard)就是這樣的設計思路:
private static List<CompleteStep<DataProcessTask>> CreateSteps(DataProcessTask o) { var welcomeModel = new WelcomeModel(o); var step1ViewModel = new UserCoreModel(o); var step2ViewModel = new UserDataModel(o); var step3ViewModel = new ConnectModel(o); var step6ViewModel = new FinishModel(o); return new List<CompleteStep<DataProcessTask>> { /// Each step contains a ViewModel and a View type (the type representing the actual Xaml to be shown). new CompleteStep<DataProcessTask> {ViewModel = welcomeModel, ViewType = typeof (Welcome), Visited = true}, new CompleteStep<DataProcessTask> {ViewModel = step1ViewModel, ViewType = typeof (UserCore)}, new CompleteStep<DataProcessTask> {ViewModel = step2ViewModel, ViewType = typeof (UserDataView)}, new CompleteStep<DataProcessTask> {ViewModel = step3ViewModel, ViewType = typeof (Connect)}, new CompleteStep<DataProcessTask> {ViewModel = step6ViewModel, ViewType = typeof (Finish)} }; }
如上圖所示,DataProcessTask類是控制整個流程的核心,第一步先例項化所需的ViewModel, 第二部,通過構建一個List列表,將View的Type的方法傳到列表中。最終管理器通過反射來例項化View,並將DataContext繫結到對應的ViewModel完成整個組裝過程。
可以看出,這種做法徹底的隔絕了View和Model, 同時通過配置選項,可以隨時修改View。可謂是一種不錯的設計。 但是,必需看到,對於View來說,Model沒有任何管理的許可權。下圖展示了它的基本邏輯:
如果最終你依舊需要兩邊互相控制,可以考慮採用dynamic關鍵字。
4. 總結
其實沒有哪種方式是最好的,完全是看你對整個系統的設計需求。但不論如何,介面和邏輯的分離,這是毋庸置疑的。下面的表格總結了幾種做法的特點和適用場合:
名稱 | 組裝邏輯 | 適用場合 | 缺點 | 備註 |
標準MVVM | View例項化Model | 常用的跨平臺場合 | Model無法控制任何View | 適用於自底向上的分層設計 |
Model例項化View | Model例項化View | 外掛結構或用於遊戲開發 | 存在一定的耦合 | 適用於按功能劃分的外掛型類庫設計,或要求Model大量控制View的場合 |
組裝車間 | 第三方管理器例項化和組裝Model和View | 可動態替換所有View | 兩者徹底隔絕,沒有控制靈活性 | 大型系統的嚴格設計 |
當然,如果用MVVMLight等第三方類庫的話,就應該按照它的方案去開發。但我們的原則是,解決問題,但不要引入更復雜的問題。為了解耦,搞了大量的複雜邏輯,反而捨本逐末。
相關推薦
WPF_MVVM 開發的幾種模式討論
在WPF系(包括SL,WP或者Win8)應用開發中,MVVM是個老生常談的問題。初學者可能不會有感覺,但當你寫一個核心邏輯能在各種平臺上無縫移植,而只需改改UI的時候,那種快感是無法用語言來形容的。 筆者當初接觸時,對MVVM並不以為然,編了很多程式碼以後,反過來看MVVM for WPF的經典
交易所系統有哪幾種模式?交易系統開發,imToken錢包開發
易信 完成後 操作 愛好 數字 比例 線下 借貸 風險 交易所系統有哪幾種模式?交易系統開發,imToken錢包開發 交易系統有哪幾種模式? (1)OTC交易系統 OTC:是一套獨立於交易所外的線下購買數字資產的平臺,任何人都可以在該平臺上發布購買/出售廣告,購買/出售用戶
hybrid幾種模式
訪問 andro 原生應用 需要 ble 依賴 綁定 內核 client native和web適合的場景 Native: 用戶體驗要求高 業務變動很小(如首頁) 性能要求高 Web: 業務變化頻繁(如廣告) 性能要求低 展
運行Spark程序的幾種模式
etc 屏幕 角色 ast java_home enabled driver env ram 一. local 模式 -- 所有程序都運行在一個JVM中,主要用於開發時測試 無需開啟任何服務,可直接運行 ./bin/run-example 或 ./bin/spark-
總結js面向對象調用的幾種模式
跟著 模式 也會 name proto bject prot .proto 混合模式 一、工廠模式:類似於function func(A,B){ var obj=new Object(); obj.A=A; obj.B=B; return obj;}; var obt
JavaScript中創建對象的幾種模式
-c aps lang mage pen lin round property mar 代碼如下: 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <met
vim的幾種模式&快捷鍵
後退 -h shell命令 識別 需要 刪除 .html 頁簽 空字符 vim的幾種模式&快捷鍵 2017年01月01日 14:05:24 閱讀數:3060 一.vim的模式 基本上vim可以分為三種模式:命令模式,插入模式和底行模式,其實vi
建立物件的幾種模式
一般建立物件是用以下兩種方式 new object建立物件: var Person = new Object(); Person.name = "張三"; Person.age = "18"; Person.job = "123"; 或者,物件字面量的方式: var Person =
創建對象的幾種模式
開發 組合 無法 只需要 toolbar 同名 工廠模式 但是 方式 一般創建對象是用以下兩種方式 new object創建對象: var Person = new Object(); Person.name = "張三"; Person.age = "18";
redis幾種模式的部署(Windows下實現)
原文地址:https ://www.cnblogs.com/yu421/p/8081544.html <參考> http://www.cnblogs.com/ruiati/p/6374152.html 1.自行下載redis客戶端.redis官方不支援Windows系統,所以官網
vim的幾種模式
Normal Mode 普通模式 功能:在這種模式下可以移動游標等。 進入:預設進入vim之後,處於這種模式。在其他模式下狂按ESC後進入此模式。 Visual Mode 可視模式 功能:在這種模式下可以選定一些字元、行、多列。 進入:在普通模式下,按v進入。 Insert Mode 插入模式
Atitit 單點登入實現幾種模式架構圖 目錄 1. 因此要點也就以下兩個:儲存信任驗證信任 1 1.1. 共享cookie (最簡單 1 1.2. 通過 url帶token引數跳轉 1 1.3.
Atitit 單點登入實現幾種模式架構圖 目錄 1. 因此要點也就以下兩個:儲存信任驗證信任 1 1.1. 共享cookie (最簡單 1 1.2. 通過 url帶token引數跳轉 1 1.3. 頁面重定向(複雜 1 1.3.1. 父子應用重定向 2
(四)高德地圖之定位的幾種模式
這一節主要實現的功能是地圖定位的幾種模式,包括展示、定位、追隨、旋轉、旋轉位置、跟隨不移動中心點、旋轉不移動中心點、旋轉位置不移動到中心點,我們根據實際需要來選擇用那種模式。下面還是主要從程式碼中來體現,主要部分有註釋。 還是先新建佈局檔案:activity_locationmodesour
DevOps--幾種模式
目錄 模式一 模式二 模式三 本文摘抄自:DevOps的概念與實踐 模式一 敏捷開發模式 通常,在軟體開發專案中,開發會用完所有計劃的時間用於開發功能,這樣會導致無法充分解決IT運維的問題,這就是開發和IT運維以及次優結果之間的永恆的緊張關
spark的幾種模式的比較
在spark的學習中,spark一共有四種模式,分別是: spark基於local spark基於standalone spark基於yarn spark基於metsos Standalone模式兩種提交任務方式 Standalone-cli
spark 環境搭建及幾種模式測試
spark 環境搭建及幾種模式測試 spark安裝部署spark安裝前的環境準備 需要安裝jdk、scala、hadoop作為前提環境。 1、安裝jdk1.7 先解除安裝自帶的jdk,防止自帶的jdk和安裝的出現衝突。而且自帶的版本較低不能滿足現在軟體對jdk的要求。 使用
字串中判斷存在的幾種模式和效率(string.contains、string.IndexOf、Regex.Match)
通常情況下,我們判斷一個字串中是否存在某值常常會用string.contains,其實判斷一個字串中存在某值的方法有很多種,最常用的就是前述所說的string.contains,相對來說比較常用的還有string.IndexOf和Regex.Match。直接上程式碼,後面在說些什麼吧,通常情況下功能的實現最
python之檔案操作的幾種模式總結
檔案操作的幾種模式: "w" #write ,清空寫,生成一
SELinux 寬容模式(permissive) 強制模式(enforcing) 關閉(disabled) 幾種模式之間的轉換
在Android的root相關的文章裡經常會看到關於SElinux,Android4.3以後引進SElinux。 ###SELinux 的啟動、關閉與檢視 1、並非所有的 Linux distributions 都支援 SELinux 目前 SELinux 支援三種模式,分別如下:
ASP.NET程式中Session儲存的幾種模式
ASP.NET程式中Session的sessionState的四種mode模式:Off、InProc、StateServer、SqlServer。 mode 可選的 SessionStateMode 屬性。 指定儲存會話狀態值的位置。有關更多資訊,請參見