BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

.NET的MVVM框架

| 作者 Roopesh Shenoy 关注 0 他的粉丝 ,译者 李永伦 关注 0 他的粉丝 发布于 2011年12月16日. 估计阅读时间: 5 分钟 | QCon上海2018 关注大数据平台技术选型、搭建、系统迁移和优化的经验。

Model-View-ViewModel是一种架构模式,主要在WPF、Silverlight和WP7开发里使用,它的目标是从视图层移除几乎所有代码隐藏(code-behind)。交互设计师可以专注于使用XAML表达用户体验需求,然后创建和视图模型的绑定,而视图模型则是由应用程序开发者开发和维护的。

MVVM是更加通用的Presentation模式的一个具体实现。MVVM视图模型包含概念模型而不是数据模型,所有业务逻辑和其它操作都是在模型和视图模型里完成的。有很多框架可以做到这点,其中一些是:

开源的

  • PRISM:由微软提供,和MEF/Unity一起用于依赖注入,支持组合命令,可以扩展MSDN上有详细的教程和演练。 
  • MVVM Light Toolkit:有visual Studio和Expression Blend的项目和项的模板。更多信息请看这里,另外可以参考VSExpression Blend的使用教程。
  • Caliburn Micro:支持视图模型先行(ViewModel-First)和视图先行(View-First)两种开发方式,通过co-routine支持异步编程。
  • Simple MVVM Toolkit:提供VS项目和项的模板,依赖注入,支持深拷贝以及模型和视图模型之间的属性关联。
  • Catel:包含项目和项的模板,用户控件和企业类库。支持动态视图模型注入,视图模型的延迟加载和验证。还支持WP7专用的视图模型服务。

闭源的

  • Intersoft ClientUI:付费的,只支持WPF和Silverlight,但是,除了MVVM框架,它还提供其它一些特性
  • Vidyano:免费但不开源。带有实体映射/虚拟持久化对象(数据容器),业务规则以及内置基于ACL的安全特性。

若想了解MVVM,可以参考以下资料:

使用MVVM的最大好处之一是分离关注点,以便用户体验设计师和应用程序开发者可以并行工作。另一方面,相关的担忧包括它对于UI操作比较简单的情况有点杀鸡用牛刀的感觉,数据绑定有点难以调试,以及大量使用数据绑定可能带来性能问题等等。


Jonathan Allen在评论里提到几点错误使用MVVM的征兆:

1. 你的模型和视图模型名字相同。

视图模型不应该是对模型的包装。视图模型的职责是外部服务的请求中介,比如加载和保存数据。而数据本身,以及验证和大多数业务逻辑应该放在模型里。

我经常强调这点。每当你创建一个视图模型包装一个模型,你就在你的API里引入一个巨大漏洞。具体地,任何直接引用这个模型的东西都可能以视图模型无法察觉的方式改变某个属性,因此UI也不会有相应的改变。同样地,模型里计算字段的任何更改也不会回传给视图模型。

2. 你的视图和视图模型名字相同。

理想的情况下,视图模型是不知道使用它们的视图的,尤其是WPF应用程序有多个窗口共享相同的视图模型。

对于比较小型的应用程序来说,整个应用程序可能只需一个视图模型。对于比较大型的应用程序来说,主要功能可能需要一个视图模型,每个次要方面也需要一个,比如配置管理。

3. 你没有代码隐藏。

代码隐藏既非一个好的东西,亦非一个坏的东西。它只是一个用来放置和视图或控件相关的逻辑的地方。因此,当我看到一个视图没有任何代码隐藏,我就会马上检查是否存在以下问题:

  • 视图模型是否通过名字接触了特定的控件?
  • 视图模型是否通过命令参数访问控件?
  • 是否使用了EventToCommand或其它可以导致泄露的行为而不是简单的事件处理程序?

MVVM Light的EventToCommand很有问题,因为它会使得控件从屏幕移除之后无法被垃圾回收。

4. 视图模型监听属性更改通知

如果一个模型的的生命周期比监听它的事件的视图模型长,那么可能导致内存泄露。不同于视图有个Unloaded事件,视图模型对于生命周期管理没有很好的方案。因此如果它们关联到存活期比它们更长的视图模型的事件,视图模型将会出现泄露。

查看英文原文:MVVM Frameworks For .NET

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

关于“你没有代码隐藏”这一点的个人看法 by 孙 长宇

关于“你没有代码隐藏”这一点,个人的看法是尽量不要在Code-Behind中出现代码,界面控件上需要的代码,一旦发现可复用性,就抽象成Trigger/Action或Behavior,除非这段代码完全不能复用的时候才会出现在当前视图的Code-Behind中。

当然,“No Code-Behind”从另一个角度上,把一些MVVM实践者带入了一个误区——乱用ViewModel,即:将本来和业务没什么关系、纯粹的界面逻辑搬到ViewModel中,以保证干净的Code-Behind,而且乐此不疲,这样的例子我见过,而且不少人这么干。

综上,个人实践MVVM的时候,关于Code-Behind的原则如下:

1 每当需要在Code-Behind中添加代码的时候,都要严格确认这段代码是不能复用的,而且仅与当前View的交互逻辑有关系,和业务逻辑没有任何关系,能复用的代码尽量分离出来,作为Trigger/Action或Behavior积累下来,这样,团队会逐渐地积累大量的有用的Trigger/Action或Behavior,这对开发效率是有利的,而且Trigger/Action或Behavior这套东西可以由设计人员在Blend中直接使用而实现功能,这也是MVVM的本意;

2 ViewModel的设计完全面向业务。Jonathan Allen所说的第一点和第二点我十分的赞同,第一点中所说的是“面向View设计ViewModel”,第二点说的是“面向Model(或是说DataModel)设计ViewModel”,这些设计都是错误的(至少我这么认为),ViewModel的设计应该完全地面向业务,根据系统的需求和复杂度确定粒度,以保证ViewModel对于View来说是可复用的模块,简单地举个例子说,AuthenticationViewModel是正确的,UserLoginViewModel和LoginDataViewModel都是错误的。

个人观点,望指教,望讨论。

Re: 关于“你没有代码隐藏”这一点的个人看法 by 李 永伦

你总结的很好啊,我也看了你在博客园上面的博文:)

Re: 关于“你没有代码隐藏”这一点的个人看法 by wei huang

说的很好. 很有道理.

mvc by Java 陈

个人觉得mvc是很好的模式,虽然MVVM可以省掉主动界面刷新,但是对于小的应用程序来说,反而显得很繁琐。而且MVVM有一定的性能损耗

而无论应用程序的规模,都可以应用MVC模式

Re: 关于“你没有代码隐藏”这一点的个人看法 by 孙 长宇

谢谢支持。

Re: 关于“你没有代码隐藏”这一点的个人看法 by Fang Xuesong

从该模式的目标来看:
[它的目标是从视图层移除几乎所有代码隐藏(code-behind)。交互设计师可以专注于使用XAML表达用户体验需求,然后创建和视图模型的绑定,而视图模型则是由应用程序开发者开发和维护的。]

是否指将视图进行图像抽象,可以通过脚本(如:XML)来进行描述,这样交互设计师可以不断体验用户的使用来实现视图。视图模型可以由应用程序开发者实现和维护,他们不需要(或少量)关注用户操作。

近期完成的一个项目也正采用了该方式,当时关键是我们的GUI部分外包到其他公司,而该公司并不了解我们的业务领域。为了使GUI更能满足客户需求,因此采用视图抽象的方式,将视图上的单个控件或一组控件抽象成数据,由真正的数据库开发人员(该项目数据为核心内容,不同客户采用不同数据也可能需要不同的用户操作)完成该视图的配置(XML编辑)。

这样外包公司之需要专注于视图模型的实现,不需要关注具体的某个视图,同时公司也可以根据客户需求定制相应的用户操作。

整个项目采用MVC架构,视图抽象只是引入的一种解决方式。

Re: 关于“你没有代码隐藏”这一点的个人看法 by 孙 长宇

让设计师专注于设计知识MVVM模式优势之一,还有一方面常常被忽略掉——ViewModel在各个View之前的复用性——这意味着更能应对复杂的需求变化。

Re: 关于“你没有代码隐藏”这一点的个人看法 by 谣 王

大哥的博客园地址是什么啊?

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

8 讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT