Model-View-ViewModel(MVVM)模式(二)

  这篇博客的目的是为了介绍Model-View-ViewModel(MVVM)模式。过去,我参加过很多关于MVVM模式的在线讨论,我发现MVVM的初学者为了在自己的代码中实现该模式,要么没有多少资料参考,要么就在费力地研究一些自相矛盾的资料。我不是要制定MVVM的规范,只是想把关键概念罗列到一篇博客中,以使读者能够更容易,更直接地理解MVVM的核心内容,实现方法。MVVM比人们想象的容易的多。

  为什么需要MVVM模式?

  作为一个开发者,为什么你应该关注Model-View-ViewModel(MVVM)模式?引入MVVM有很多的好处,在这之前,先尝试着问自己一些问题:

  (1)你需要和设计师协作工作吗?你需要让几乎同时进行的设计工作和开发工作具有更高的灵活性吗?

  (2)你的解决方案需要进行单元测试吗?

  (3)在项目、甚至是公司里面重用一些公共组件对你来说是重要的吗?

  (4)在不修改代码块中的业务逻辑的前提下,你想要更灵活地修改用户界面元素吗?

  如果对于上述问题中的任一个,你的答案是%26ldquo;Yes!%26rdquo;,那么采用MVVM模式能够给你的项目带来一点帮助。

  我对网上的一些言谈感到很吃惊,例如%26ldquo;MVVM只对非常复杂的界面设计有意义!%26rdquo;,%26ldquo;对于小规模的应用程序,MVVM总会增加很多额外的开销。%26rdquo;,更好笑的说法是%26ldquo;MVVM是不可扩展的。%26rdquo; 就我而言,上面的说法说的是MVVM的实现,而不是MVVM自身。换句话说,如果你需要花费数小时理解MVVM,你的做法就是错的。如果你的应用程序扩展性差,别怪MVVM,要怪你自己是如何使用MVVM的。不管你采用何种设计模式,向ListBox绑定100000项列表项的做法都是愚蠢的。

  当然,这只是我知道的MVVM,不是被广泛认可的MVVM。

  Model-View-ViewModel(MVVM)模式,分为三层,分别是View层,ViewModel层,Model层,下面进行具体的介绍。

  Model层

  我把Model类比为领域对象。Model负责保存数据,管理状态。一个Model的例子是通讯录,每个联系人的信息包括姓名,电话,地址等等。Model的关键概念是保存数据,但是不操作数据。Model不负责将将文本格式化供屏幕显示来获得好的用户体验,也不负责从远程服务器上读取列表的选项数据。(事实上,列表中的每一个选项都更像是自己的Model。)业务逻辑通常是与Model分离开来的,被封装到与Model进行交互的其他类中,但也不是一种定律,有些情况下,Model中也会包括验证服务。建立纯粹的Model是一种挑战,我说的是一种代表%26ldquo;真实世界%26rdquo;的Model。例如,一条通讯记录可能包含最近修改日期,联系人的身份信息,和一个唯一的标识符(在数据库中存储的关键字诸如此类的信息)。在真实世界中,最近修改日期对通讯录是没有意义的,仅仅是作为一项功能在系统中跟踪Model是如何使用的。

  View层

  View层是我们大多数人熟悉的部分,同时也是用户唯一能够和系统交互的部分。View层负责显示数据。View能够在显示数据之前对其进行格式化,例如,存在在数据库中的日期可能是自1970年以来的毫米值,但是对于终端用户来说,他们看到的是当地时区年,月,日。View也能够接受来自用户的输入。View管理各种类型的输入,如键盘,鼠标,手势等,这最终将使用Model中的属性值。

  在MVVM中,View是主动的。和与Model无关联的,完全由Controller和Presenter操作的被动View相反,MVVM中的View包含着交互,事件,数据绑定等操作,这最终将会关联到底层的Model和ViewModel。当这些事件和交互被映射到属性,方法调用,命令的时候,View会继续负责处理自己的事件,而不会将所有的操作委托给ViewModel。另外,需要注意的是View不再保持自己的状态信息,而是选择与ViewModel的数据同步。

  ViewModel层

  ViewModel是三层中的关键部分,因为它引入了表示分离的概念。相较于View直接使用Model中的原始数据,ViewModel首先将数据格式化,从而使Model只保存原始数据,View只显示格式化数据。ViewModel作为控制器,充当两者之间的联络员,ViewModel可能会接收来自View的输入,然后更新Model中的数据,或者通过接口与Model交互,然后翻译属性值以在View上显示。

  ViewModel也会提供一些接口,命令或其他的接入点来帮助View保存状态,基于View上的交互结果操作Model,和触发View自身的事件。

  View和ViewModel之间的交互

  (1)View和ViewModel之间通过数据绑定,方法调用,属性值,事件,消息进行交互;

  (2)ViewModel提供的接口调用不但包括来自Model的数据,还有属性值(如,状态信息,%26ldquo;isBusy%26rdquo;标识符),命令等。

  (3)View处理自身的事件,然后通过命令将其映射到ViewModel;

  (4)Model层的数据和ViewModel层的属性值通过双向的数据绑定更新数据;

  ViewModel和Model之间的交互

  (1)ViewModel可能直接使用Model,或者将属性值与Model相关联。

  (2)为了操作供View调用的属性值,ViewModel可能包含一些服务接口,配置参数。

  先有鸡还是先有蛋的问题?

  你可能会听过关于先有View还是先有ViewModel的讨论?总的来说,我相信大多数开发者同意每一个View都有一个唯一与之对应的ViewModel,没必要为同一个View绑定多个ViewModel。如果你考虑过分离的概念,这就很有意义。一个View可能由许多其他View构成,每一个View都有自己的ViewModel。ViewModel有时也可能包含多个其他的ViewModel。虽然一个View应该只有一个ViewModel,但是一个ViewModel能够被多个View共享。

  关于上述问题的答案,一种观点是先有View,这意味着View驱动ViewModel开发。在这种场景中,View通常作为一种资源,利用依赖注入与ViewModel绑定。另一种先有ViewModel的观点意味着ViewModel负责创建View,同时将自身绑定到View。

  总结

  MVVM不是一个完整的框架,它只是一种设计模式。MVVM不处理,事实上也不关注你的服务器上发生了什么,或者你的服务是怎么组织到一起的。MVVM只是强调一种表示分离的概念。

%26nbsp;

  到此,对技术文摘Model-View-ViewModel (MVVM) Explained的翻译结束,希望能够增加读者对MVVM模式的认识。

%26nbsp;

  参考文献:

%26nbsp;

    [1] 英文原文:Model-View-ViewModel (MVVM) Explained

%26nbsp;

  本文历史:

%26nbsp;

  • 2015-08-05  初稿完成。

%26nbsp;







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值