深入理解MVVM模式

2015-10-21 17:21谢伟
速读·下旬 2015年12期
关键词:用户界面设计模式分层

谢伟

摘 要:MVVM即Model-View –ViewModel,是微软WPF和Silverlight应用特有的一种界面设计模式。使用MVVM设计模式可以帮助我们分离业务逻辑,显示逻辑和用户界面,使得我们的程序代码结构清晰,容易被阅读、测试、维护、替换、扩展和改进。

关键词: MVVM;设计模式;分层;用户界面

一、什么是MVVM模式

MVVM是Model-View-ViewModel的简写。微软的WPF带来了新的技术体验,如Silverlight、音频、视频、3D、动画……。这导致了软件UI层更加细节化、可定制化。同时,在技术层面,WPF也带来了诸如Binding、Dependency Property、Routed Events、Command、DataTemplate、ControlTemplate等新特性。MVVM(Model-View-ViewModel)框架的由来便是MVP(Model-View-Presenter)模式与WPF结合的应用方式时发展演变过来的一种新型架构框架。它立足于原有MVP框架并且把WPF的新特性揉合进去,以应对客户日益复杂的需求变化。

二、为什么要有MVVM模式

开发UI,对一个专业软件并不容易。它需要未知数据、交互式设计,可视化设计、联通性,多线程、国际化、验证、单元测试以及其他的一些东西才能完成。考虑到UI要展示开发的系统并且必须满足用户对系统风格不可预知的变更,因此它是很多应用程序最脆弱的地方。

有很多的设计模式可以帮助解決UI不断变更这头难缠的野兽,但是恰当的分离和描述多个关注点可能很困难。模式越复杂,之后用到的捷径越可能破坏之前正确的努力。

自从人们开始构建UI时,就有很多流行的设计模式让UI构建更容易。比如,MVP模式在各种UI编程平台中都非常流行。MVP是MVC模式的一种变体,MVC模式已经流行了几十年了。MVVM比MVP更加简单,更不用说MVC了。MVVM是在MVP之后出现的一种“更好的”UI模式解决方案。

如图1,展现了MVVM是如何做到井然有序的。

图1  MVVM模式图解

(1)View中很多控件的数据类型和Model中的属性不相同,例如开发中,性别这种,Model中很可能就放置一个bool类型的变量。但是在前台的展现View中,用户看到的应该是“男”和“女”。这就需要一种转化。

(2)在WPF开发中事件和命令同样都可以让一个UI正常的工作。我们知道Winform是事件驱动的。所以理所当然使用事件更容易理解和实现。但是带来的问题是后期的庞大与多种多样的事件。

这两种问题很大的催生出Model和View中间的一个辅助角色ViewModel。它需要帮助View转化相应的数据给Model或者从Model处转化成View可以显示的内容。同时它也需要将View的多种命令绑定给Model中的处理方法上。这些命令可以复用,当其他View需要的时候,同样可以调用命令中绑定的方法。ViewModel可以看成一个变种的Controller。

三、实现原理

解决了上一节提出的两个问题,实际上就解决了ViewModel的全部工作原理。

首先,从Binding问题入手。在View中的控件存在一个属性,叫做“DataContext”。这个是控件数据使用的源头。DataContext属性会给控件指定一个后台模型,使得该控件使用的数据都是来自于这个模型类。所以,ViewModel应该充当这个后台模型的作用,给View的控件提供显示数据。同时,ViewModel的数据应该是来自于背后的Model所提供的。所以,简要的说,根据View中显示的数据是何种Model,来定义ViewModel。举个例子,如果View构造了一个TextBlock控件,想要显示的仅仅是Model中的一个string。那么在ViewModel中,应该引用这里的Model,这样作为View部分,就可以调用这个Model的某个string属性了。

其次,解决Command问题。WPF中已经构建了实现了ICommand的类RoutedCommand和RoutedUICommand。针对于不同的View事件,单独使用哪一种都不是全权之策。因此,需要定义一个实现了ICommand接口的类。目前网上有现成的DelegateCommand和RelayCommand两种解决方法。他们的共同点都是实现了ICommand接口,同时对于不同的事件,都可以绑定Model不同的处理方法。其区别是:i)DelegateCommand使用了一个RaiseCanExecuteChanged方法,需要开发者手动来触发控件可执行判断。而RelayCommand中对于此处的触发判断是代理给CommandManager自己判断了。更加方便;ii)DelegateCommand因为是开发者手动控制的,所以资源占用低,而RelayCommand在各种命令触发的时候都需要判断一下。所以资源占用也相对较高。这一点尤为能体现在复杂的系统中。所以使用哪一个都是看开发人员自己选择。当然也可以自己手动写一些更加适合自己的XXXCommand。其实现原理就是实现了ICommand接口。另外,使用委托的方法,将无返回值的Execute使用Action委托,有返回值的CanExecute使用Func委托。

参考文献:

[1]陈明、李猛坤、张强.一种基于扩展MVVM模式的SaaS面向服务计算模型[J].微电子学与计算机,2010年08期

[2]李猛坤、陈明.一种基于扩展MVVM模式的面向服务软构件模型[J].科学技术与工程,2011年10期

猜你喜欢
用户界面设计模式分层
自然用户界面在智能家居系统中的应用路径创新研究:生成式人工智能技术的调节作用
“1+1”作业设计模式的实践探索
基于CiteSpace的国外用户界面体验图谱量化分析
三维协同设计模式下的航天项目管理实践与展望
一种沉降环可准确就位的分层沉降仪
交通机电工程设计模式创新探讨
雨林的分层
基于B/S的跨平台用户界面可配置算法研究
互动式设计模式研究
跨越式跳高递进与分层设计