[转载]MVVM模式原理分析及实践
没有找到很好的MVVM模式介绍文章,简单找了一篇,分享一下。MVVM实现了UI\UE设计师(Expression Blend 4设计界面)和软件工程师的合理分工,在SilverLight、WPF、Windows Phone开发中得到很好的应用,当然作为设计模式的结合体,提供的是软件设计的一种思路,业务场景符合其设计思路,都可以很好的利用。
原文如下:
摘要:为解决适用于RIA应用系统开发的设计模式的问题,提出引出MVVM模式。该模式由视图、视图模型、模型三部分组成,通过实现INotifyPropertyChanged接口,解决模型到视图模型的数据传导问题,使模型独立于视图模型,通过实现ICommand接口,解决视图中的事件绑定问题,结合数据绑定,使视图模型独立于视图。通过实现 Mediator模式(中介者模式)完成模型与模型之间的交互,并在一定程度上减少模型与模型之间的耦合度。
1引言
RIA(Rich Internet Application)技术是近年来发展较快的实现Web2.0应用开发的技术,与传统的Web应用相比,RIA技术更加追求更丰富的用户体验。适应这种变化,RIA应用系统开发过程的分工要求更加细致,一部分人负责界面设计,一部分人负责业务逻辑设计。这种分工写作给软件设计模式带来新的要求,一方面要保持系统易于理解和维护、良好的扩展性和低耦合度,另外一方面要追求业务逻辑、呈现逻辑和UI逻辑的分离,使得界面设计和程序控制开发可以同步进行。目前在RIA应用系统中开发使用比较多的有MVC(Model-View-Controller)、MVP(Model-View-Presenter)等设计模式,但是这些模式并不能完全将UI设计分离。为此将呈现逻辑从视图中独立出来,同时将界面数据从模型中独立出来,组成视图模型(ViewModel)模块,形成了MVVM(Model-View-ViewModel)模型,我们可以认为MVVM是MVC的变种。MVVM模式不但能够实现UI设计的分离,而且能充分发挥RIA技术中的数据绑定的技术和特点,提高软件的复用性。
2.Silverlight简介
Silverligh是由微软推出的跨浏览器、跨平台的Web前段应用开发解决方案,是微软RIA策略的主要应用开发平台之一,以浏览器的外挂组件方式,提供Web应用程序中多媒体与高度交互性前端应用程序的解决方案,同时也是微软UX(用户体验)策略中的一环,也是微软视图将美术设计和程序开发人员的工作明确切分与协调合作的发展应用程序的尝试之一。
3.MVVM简介
MVVM模式是Model-View-ViewMode模式的简称。由视图(View)、视图模型(ViewModel)、模型(Model)三部分组成,结构如下图。通过这三部分实现UI逻辑、呈现逻辑和状态控制、数据与业务逻辑的分离。
![](http://www.cpiso.cn/jsyj/ghxx/images/2012/05/20120518110416781.jpg)
使用MVVM模式有几大好处:
1. 低耦合。View可以独立于Model变化和修改,一个ViewModel可以绑定到不同的View上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
2. 可重用性。可以把一些视图的逻辑放在ViewModel里面,让很多View重用这段视图逻辑。
3. 独立开发。开发人员可以专注与业务逻辑和数据的开发(ViewModel)。设计人员可以专注于界面(View)的设计。
4. 可测试性。可以针对ViewModel来对界面(View)进行测试
4. 模型、视图、视图模型的分工
1. 视图(View)
视图负责界面和显示。它通过DataContext(数据上下文)和ViewModel进行数据绑定,不直接与Model交互。 可以绑定Behavior/Comand来调用ViewModel的方法,Command是View到ViewModel的单向通行,通过实现Silverlight提供的IComand接口来实现绑定,让View触发事件,ViewModel来处理事件,以解决事件绑定功能。
2. 视图模型(ViewModel)
视图模型主要包括界面逻辑和模型数据封装,Behavior/Command事件响应处理,绑定属性定义和集合等。它是View和Model的桥梁,是对Model的抽象,比如:Model中数据格式是“年月日”,可以在ViewModel中转换Model的数据为“日月年”供View显示。
实现视图模型需要实现Silverlight提供的接口INotifyPropertyChanged, INotifyPropertyChanged接口用于实现属性和集合的变更通知(Change Notifications)。使得在用户在视图上所做的操作都可以实时通知到视图模型,从而让视图模型对象有的模型进行正确的业务操作。
View的代码隐藏(Code-Behind)部分可能包含界面逻辑或者应用逻辑的代码,这些代码会很难进行单元测试,应根据具体情况尽量避免。
![](http://www.cpiso.cn/jsyj/ghxx/images/2012/05/20120518110416828.jpg)
图2 View、ViewModel和Model的交互图
Mediator模式
对不同View、ViewModel之间的参数传递,一般通过事件实现数据传递,也可以定义全局静态变量来进行数据共享,在MVVM里,我们可以使用Mediator模式(中介者模式)进行跟优雅的处理。可以简单得理解为不同的ViewModel或者View需要进行了操作之后,需要其他ViewModel或者View进行相应的其他操作或者数据更新,而中介类可以准确得将更新准确得通知到正确的ViewModel,同时中介者并不关心ViewModel或者View的任何操作或者数据更新。
![](http://www.cpiso.cn/jsyj/ghxx/images/2012/05/20120518110416875.jpg)
图3 ViewModel通过Mediator模式与其他ViewModel的交互图
3. 模型(Model)
Model与MVC模式一样,Model用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法。它具有对数据直接访问的权利,例如对数据库的访问,Model不依赖于View和ViewModel,也就是说,模型不关心会被如何显示或是如何被操作,模型也不能包含任何用户使用的与界面相关的逻辑。Model在实际开发中根据实际情况可以进行细分。比如在广州市城乡规划资源平台就将Model将Service和Reposiroty结合为WCF服务由ViewModel进行调用。
![](http://www.cpiso.cn/jsyj/ghxx/images/2012/05/20120518110416953.jpg)
图4 Model的细分层次关系
为了更好的说明MVVM模式,图5是广州市城乡规划资源平台实现MVVM模式设计的类结构图。
![](http://www.cpiso.cn/jsyj/ghxx/images/2012/05/20120518110417078.jpg)
4.Silverlight和MVVM模式的综合应用实践
广州市城乡规划空间资源平台
一、 概述
广州市城乡规划空间资源平台是一个面向城市规划的GIS系统。通过对该系统的建设以满足规划编制、规划管理、规划实施动态监控三方面的需求实现GIS与OA、GIS与CAD的图文一体化。提高城市规划科学性和管理水平,实现统一规划、资源整合、信息共享、开放服务等目标。
二、技术特点
项目采用WebService技术搭建跨平台的、可互操作的分布式应用程序平台,采用Silverlight技术,使用了MVVM模式,结合GIS Server服务和Web Service服务等进行开发。
系统中对于地图显示并不是每一个服务都需要加载,服务的地址,加载情况,默认设置这些可以作为一个地图服务数据模型(MapServiceInfo)。
下图为平台对地图服务数据模型的部分定义
![](http://www.cpiso.cn/jsyj/ghxx/images/2012/05/20120518110417140.jpg)
图6 地图数据模型部分定义
为了实现对该Model的控制,建立视图模型MapViewModel,在其中实现对数据模型的加载默认图层、增加服务图层,打开\关闭图层等操作的控制,服务的获取等操作。用户对视图的任何操作都会对视图模型进行一次变更通知,从而使视图模型可以实时对模型进行相应操作。
实现视图模型MapViewModel需要实现Silverlight提供的接口INotifyPropertyChanged, INotifyPropertyChanged接口用于实现属性和集合的变更通知(Change Notifications)。使得在用户在视图上所做的操作都可以实时通知到视图模型,从而让视图模型对象有的模型进行正确的业务操作。
下图为广州市城乡规划资源平台中对INotifyPropertyChanged接口的实现方式:
![](http://www.cpiso.cn/jsyj/ghxx/images/2012/05/20120518110417187.jpg)
图7 MapViewModel对接口INotifyPropertyChanged的实现
建立完视图模型之后,在各个视图中通过DataContext(数据上下文)与视图模型进行绑定,通过相应的Command对视图模型进行操作。Command是View到ViewModel的单向通行,通过实现Silverlight提供的IComand接口来实现绑定,让View触发事件,ViewModel来处理事件,以解决事件绑定功能。IComand接口结构如下所示:
![](http://www.cpiso.cn/jsyj/ghxx/images/2012/05/20120518110417250.jpg)
图8 ICommand接口描述
由于Silverlight对ICommand的功能支持并不多,为此需要对ICommand接口进行实现来提供View和ViewModel之间的事件绑定。下图为广州市城乡规划资源平台中对ICommand接口的实现方式:
![](http://www.cpiso.cn/jsyj/ghxx/images/2012/05/20120518110417281.jpg)
图9 对ICommand接口的实现
然后通过在MapViewModel中添加相关ICommand接口的属性,以供View进行绑定使用。如下图:
![](http://www.cpiso.cn/jsyj/ghxx/images/2012/05/20120518110417359.jpg)
图10 在ViewModel中添加相关ICommand属性
具体的类结构图如图7所示。
接着完成View对MapViewModel的绑定操作,这里我们可以通过Microsoft Expression Blend这个工具来完成。以图层管理面板为例,下图是通过Blend工具设计好的View界面:
![](http://www.cpiso.cn/jsyj/ghxx/images/2012/05/20120518110417468.jpg)
接着开始进行View到ViewModel的绑定过程,在相关View中选择DataContext,选择Data Binding…:
![](http://www.cpiso.cn/jsyj/ghxx/images/2012/05/20120518110417515.jpg)
图11 给View绑定DataContext
在弹出的面板中选择Data Field分页,选择Data sources的Fields,找到名为MapViewModel的项,点击OK按钮,完成View对ViewModel的绑定。
![](http://www.cpiso.cn/jsyj/ghxx/images/2012/05/20120518110417625.jpg)
除了绑定ViewModel之外,还需要对相关的事件进行绑定,在当前View界面中提供了“增加数据”的功能按钮,选择功能按钮,在右侧的属性面板中找到Miscellaneous分页,选择Command属性,右键打开设置面板,选择Data Binding…
![](http://www.cpiso.cn/jsyj/ghxx/images/2012/05/20120518110417687.jpg)
图13 绑定Command(一)
在弹出的面板中选择要进行绑定的Command点击OK按钮进行绑定,如图所示
![](http://www.cpiso.cn/jsyj/ghxx/images/2012/05/20120518110417781.jpg)
在View绑定ViewModel的过程中是完全可以由界面设计师来进行操作,而不进行任何编码的。至此,完成MVVM设计模式的一个过程。
效果图
![](http://www.cpiso.cn/jsyj/ghxx/images/2012/05/20120518110417875.jpg)
如下视图均使用MapViewModel作为视图模型来操作数据模型完成相关操作。
1)图层管理面板:用户通过此面板进行图层服务的查看和加载操作。对于已经加载的服务以红色字体显示。用户可以通过设置数据添加位置来决定服务添加在哪一层。
![](http://www.cpiso.cn/jsyj/ghxx/images/2012/05/20120518110418015.jpg)
2)图层控制面板:用户通过此面板进行图层的显示控制。提供热点图层、和图层搜索功能简化用户查找图层的操作。
![](http://www.cpiso.cn/jsyj/ghxx/images/2012/05/20120518110418093.jpg)
图17 图层控制面板
3)条件组合查询:用户通过在面板中选择特定的图层服务,选择所需字段构建查询条件完成查询操作,从而获取相应的数据结果。对显示的结果,用户可以点击结果项,地图将自动定位至选中项。
![](http://www.cpiso.cn/jsyj/ghxx/images/2012/05/20120518110418187.jpg)
![](http://www.cpiso.cn/jsyj/ghxx/images/2012/05/20120518110418312.jpg)
结语
MVVM模式很好的将UI逻辑分离开来,使得在开发过程中设计师和代码编写员中可以很好地完成自己的职责。从而保证了程序的低耦合,可重用性,独立开发和可测试性。
原文链接:http://www.cpiso.cn/jsyj/ghxx/2012/5/18/373.shtml
另几篇相关博客:
《WPF中的MVVM模式》
《MVVM架构的简单解析》
《 .NET MVVM设计模式简介》
《 [转载]MVP(SC),MVP(PV),PM,MVVM 和 MVC 表现模式架构对比》