打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
MVVM经验之谈

  今天上午看到InfoQ上的文章《.NET的MVVM框架》,当时就有写点什么的冲动,但不知道从哪里开始,就不了了之了。后来在博客园上又看见转载,两边都是一样,一条评论都没有,实在忍不住,就写了条评论在InfoQ的文章下,后来又觉得做MVVM实践这么长时间了,眼看要不做了,写篇博文,权当总结,与园友共讨论之。

  最开始接触MVVM,是从我刚来万网开始的,那时候的我刚刚做了将近一年的Silverlight,刚刚出来工作不到两年,对什么“设计模式”之类的还是刚刚接触,那时候,还是很幼稚的我,凭借在方正的Silverlight开发经验,来到了万网,开始新的工作。

  新的工作仍然是Silverlight开发,刚来的第一天就听到了一个我之前只是草草看过的概念——MVVM。当时一起做Silverlight开发的只有三个人(另两个兄弟,希望你们也能看到这篇博文),他们俩对MVVM了解的挺多的,不甘落后的我就开始废寝忘食地钻研MVVM。从简单实现,到Prism,到自己设计接口,实践中一次次地痛苦,一次次的失败,一次次地讨论,一次次地实践,现在回想起来,那段日子竟是我在万网最快乐的日子。

  使用新技术改造老系统的难度本身就很大,再加上新模式的实践,我们遇到了很大的困难,最开始,我们就是与老代码做斗争,包装了一层又一层,没办法,一步一步艰难地往前走。遇到的问题,比如说数据模型没有属性改变通知、Silverlight端的底层只支持同步访问(我们不能直接访问WCF,有人封装好)等,都一一想办法解决了。

  后来,我被调到另一个项目组做组长,其中有一项任务就是努力做好MVVM实践(在此感谢那位领导)。这个组中,有一个专职的XAML开发(在此感谢你),这对我的帮助很大,因为验证MVVM实践是否成功的最直接办法就是让一个不懂C#只懂XAML的人去完成所有的用户界面(包括交互)制作,如果他完美地完成了,那么你的实践在很大程度上程度上来说就是成功的,否则就一定是失败的。(注:这里,Action、Behavior的开发还是需要C#开发协助的,XAML开发要向C#开发提需求。)

  她做到了(没错,是“她”)!她很好地完成了用户界面制作的工作,只需要一开发向她提供少量的代码支持就可以,从这个角度上说,我们取得了初步的成功。

  不过做到这一点之后,我开心不起来,为了实现这个目标,我们做的筋疲力尽,在原有的底层上又包装了一层,数据服务、查询表达式等等统统包装了一层,从数据服务层往上看,哇,赏心悦目,干净整洁,MVVM的大楼!但是往下看,数据服务端为了简化上层的开发,做了很多牺牲,说白了,代码很乱,充满了危险的信号,这个,有老代码的问题,当然也有我的问题。

  再后来,就当我们的实践有了基本的框架,要开始做功能的时候,我在下班的时候以30KM/h的速度与一辆旅游大巴车相撞(这一天刚好是我来万网一年整),左足跟软组织开放性外伤,住院8天回家养伤三个月。命大,足跟愈合了,三个月后,我又回到了公司,这时候,一切都陌生了。打开原来我熟悉的代码,有一些凄凉,甚至有一些陌生,我的MVVM,现在是这个样子了。

  废话好像多了,再多就变成回忆录了,但是博客园上还是要写技术博文的。基于InfoQ上的那篇文章,我写了条评论,写了部分我们做MVVM实践时要把握的原则,这里再次总结原则和要点如下:

1   不要在View的Code-Behind中添加任何代码,除非这段代码没有任何复用性且只与当前页面交互逻辑有关;
2   ViewModel的设计要面向业务,面向数据会增加系统实现的复杂性,面向视图会降低ViewModel的可复用性;
3   ViewModel中不能掺杂任何与界面交互逻辑相关的东西(比如说IsExpanded,ShowDialogCommand之流);
4   Action/Behavior做为团队整体的积累,很重要,要保证质量,积累下来的东西要保证是可复用的;
5   ViewModel和View同时面向需求去设计,这样就能保证最终提供给View的ViewModel能够实现需求,不要让ViewModel为了View去做改变,一切看需求;
6   功能性的东西,可以封装到Command中,由ViewModel组装相应的Commands来实现某种功能;
7   ViewModel和Command粒度的划分要根据系统复杂度确定,简单的系统,粒度太细会增加复杂程度;
8   对于老系统改造来说,底层和数据层都要有大的改变,这是必然的;Silverlight使用同步方式与服务器交互是一种错误
9   团队中所有成员对MVVM的认知要基本一致,否则会做出来的东西,你自己看吧,你自己都不认识;
10 严格的代码审查是很有必要的,毕竟这是一种尚未成熟的模式的实践,团队成员对模式的理解稍有偏差就会对代码产生非差大的影响;

  还有很多啦,当然这也都是我浅薄的经验的总结,如有错误或不同意见,请大家批评指正,也欢迎大家讨论。

人活着就要有他自己的意义,否则他就和死了没什么两样!!
分类: Silverlight
标签: Silverlight, MVVM
7
0
(请您对文章做出评价)
博主前一篇:【小技巧】Silverlight Blend SDK中的dll文件也可以使用应用程序库缓存
博主后一篇:C#基于Lambda递归的阶乘/累加实现
posted @ 2011-12-16 19:03 孙长宇 阅读(3622) 评论(28) 编辑 收藏

  
#1楼 2011-12-16 19:18 | 撞破南墙  
想问,有谁总结了mvvm需要的编程语言或框架特性的支持,还可以应用在哪些其他哪些地方?

另,祝好。

  
#2楼 2011-12-16 19:25 | xuefly  
借此宝地打个广告:希望传说中的弦哥快些写下篇我等着看呢。

  
#3楼 2011-12-16 20:18 | Allen Lee  
果然是经验之谈!

  
#4楼 2011-12-16 20:35 | Mainz  
SL同仁路过支持!

  
#5楼 2011-12-16 21:09 | 菜鸟老了  
@撞破南墙
prism

  
#6楼 2011-12-16 21:18 | 银光小子  
嘻嘻 不妨关注一下 我的 TagSL 编程框架

  
#7楼 2011-12-16 22:44 | allanxyq  
总结的不错

  
#8楼 2011-12-16 23:24 | garfieldzf  
呵呵, 中国万网, 周方宇带项目。

呵呵,学习。

  
#9楼 2011-12-17 09:54 | Jake Lin  
果然是经验之谈,我要细细体会,谢谢!

我觉得MVVM是很复杂的模式,学习成本很高,但是可能维护成本减低。

“ViewModel中不能掺杂任何与界面交互逻辑相关的东西”
请问这个怎么处理?我一般放一些IsLoading,启动动画的依赖属性,用此更新View。

  
#10楼[楼主] 2011-12-17 12:23 | 孙长宇  
@撞破南墙
这个还真不太好说,慢慢总结慢慢积累吧。
不过我倒是有个建议,从本质上自己设计一下,有一定的实践之后再看Prism这类框架。

  
#11楼[楼主] 2011-12-17 12:24 | 孙长宇  
@garfieldzf
额……周方宇不认识。

  
#12楼[楼主] 2011-12-17 12:36 | 孙长宇  
@Jake Lin
“ViewModel中不能掺杂任何与界面交互逻辑相关的东西”,但是可以包含和内部运行状态相关的东西,比如说,异步操作的“IsBusy”,异步操作的“OperationSuccesed”、“OperationFailed”之类的。
不知道这么说能不能解决您的问题。

  
#13楼 2011-12-17 15:58 | Jake Lin  
@孙长宇
我现在也是这样做的,OperationSuccesed,我是通过Messager来更新。

  
#14楼 2011-12-18 11:12 | 通通的成长日记  
@孙长宇
学习了,今年毕业的我,3层都由我一个人在做,我表示满足经理的界面需求压力很大.....

  
#15楼[楼主] 2011-12-18 13:13 | 孙长宇  
@通通的成长日记
嗯,三层都由你来做,有个问题,就是没人帮你验证。

  
#16楼 2011-12-19 10:32 | 羽之  
对于mvvm有下列几个问题:
1、很多操作是从后端返回信息,这些信息需要一种提示方式在view。在这种情况下,除了用委托这种费时费力的方法还有什么好方法吗?
2、在绑定无法抓到数据的情况下,如何使用mvvm,如textchanged事件。

  
#17楼 2011-12-19 10:45 | bk7477890  
路过加关注~~亲

  
#18楼[楼主] 2011-12-19 11:03 | 孙长宇  
@羽之
关于第一个问题:
数据绑定。还有,个人不认为委托和事件非常费时费力,至少我的实践中没有因为委托和事件遇到什么困难,不过有时候要注意对象释放的问题。
关于第二个问题:
没太明白你的意思,如果你是想在TextChanged事件中触发什么命令或者触发绑定通知的话,可以尝试使用Trigger/Action/Behavior解决问题。

  
#19楼 2011-12-19 11:04 | ChrisPei  
现在MVVMLight已经是我们基本框架之一,嘿嘿~

验证MVVM实践是否成功的最直接办法就是让一个不懂C#只懂XAML的人去完成所有的用户界面(包括交互)制作

这个其实是一个很不错的实践,对于初学MVVM的人来说可以强制使用这样的办法来学习,这样的话一定会遇到很多MVVM模式上的问题,强迫你从传统的模式过渡到MVVM。如此一个小项目做下来,MVVM自然了然于心了。

学习过程中不要回避XAML,学会使用Blend去设计。XAML要比你想象的能干很多!

  
#20楼 2011-12-21 17:25 | 漠漠不懂  
万网常年的搞silverlight 招聘 原来就这么几个人.

  
#21楼 2011-12-22 13:37 | 羽之  
@孙长宇
如果你一个界面有40个项目,并且他们的绑定还完全独立,你写个看看,光你viewmodel的属性就要命了

另外,你如果像光标离开,textchanged这种事件还要用触发器,你看看你的xaml要乱成什么样,后面的viewmodel代码的可读性和完整性会变成什么样。

还有,触发器和行为会增加xap包的大小,所以一般我不喜欢使用

  
#22楼[楼主] 2011-12-22 17:39 | 孙长宇  
@羽之
“如果一个界面有40个项目”,这样也不会乱,除非你的项目中根本没有“Model”这个概念;

“触发器和行为会增加xap包的大小”这种事个人感觉不完全正确,引用Blend SDK固然会增加XAP包大小,但是“System.Windows.Interactivity.dll”也不过36.5KB而已,类似于“TextChangedTrigger”这样的东西,没有必要引用“Microsoft.Expression.Interactions.dll”(87.0KB),自己写一个就好了,这也是代码积累,是可复用的模块。

还有啊,我没明白为什么使用Trigger/Action/Behavior会影响到“viewmodel代码的可读性和完整性”,请举实例。

而且,任何事物都是有两面性的,MVVM有其好处和优点,必然有其不足,这个是可以讨论和批判的,但是要理性地看待缺点和优点,最重要的是“平衡”。

  
#23楼 2011-12-24 11:08 | 羽之  
@孙长宇
我不知道你用MVVM所涉及的行业。所以可能我们的环境有差异

首先,是存在一个界面中涉及多个model的情况,如:用户名、未读信息、最近访客等信息在一个界面上展示,实际上的信息量比这个更多。在这种情况下,你用MVVM的工作量一定要比直接写大。

其次,texchenged的问题不是触发器或行为,而是你无法在绑定属性中得到录入的值。你可以试一下。只有this.texbox1.text属性有效,绑定的值为null。这样我是没法用mvvm来实现的

实于平衡,在现状有几个问题,使我没法实现mvvm
1、没有会blender的UI设计人员
2、sl开发者能力偏低
3、mvvm实现成本过大
4、部分情况无法使用mvvm

我觉得除非能解决这4个问题,其实最重要的是1和4两个问题。否则mvvm实现是不太可能的

  
#24楼[楼主] 2011-12-24 15:19 | 孙长宇  
@羽之
一个界面中涉及多个Model,包含大量数据表单的情况下,写Model的确会增加最开始的工作量,但是会较小重构难度,这个需要平衡掌握。

“无法在绑定属性中得到录入的值”的问题,我通过一个行为解决了这个问题,对这个行文的描述是“当文本框文本发生改变时更新当前绑定”,这个代码现在不在我手头,有机会私聊发给你,可以讨论一下。

关于你提到的四个问题:
1 见当前博文正文,我的团队中培训了这样一个人才,专职Blend开发哦。
2 这个是实话,这个也是我在本文中提到“队中所有成员对MVVM的认知要基本一致”的原因。
3 实现成本过大我不同意,这个要看具体情况,对于小项目来说,这个的确会增加设计和开发成本,但是对于大项目和需求经常变化的项目来说,如果MVVM实践的好,可以大大降低维护和重构成本。
4 我们做了一年,很多情况我们都遇到过,遇到情况我就会召集小组中的人一起讨论去解决,“绑定更新行为”就是这样讨论出来的。这样还有个好处,就是能逐渐统一小组中成员的思想。

  
#25楼 2012-01-01 13:20 | 超然  
本人做了半年的MVVM,博主说的我多少都遇到了,的确是经验之谈。不过关于第三点说道的问题很麻烦,多少会有界面上的东西,还有两个问题不知道博主如何解决的。
1、子窗体调用:我是在子窗体的VM中直接new子窗体的View然后显示,这样在调用时不用知道具体的View,只要知道VM就可以了
2、页面导航参数如何获得:page导航时的参数如何在VM中获得,我是给VM做了接口,在page后置代码中直接转换DataContext后传进去。
-------
现在越来越发现MVVM模式越来越像MVC了,VM就是控制器,决定了用那个模型填充那个View,甚至按照需求都可以呈现不同的View。

  
#26楼[楼主] 2012-01-03 16:16 | 孙长宇  
@超然
这样来回回复太累了,我给你发私信,私信中有我的联系方式,需要讨论的话加我吧。

  
#27楼 2012-01-17 16:29 | Libra.Thinker  
@Jake Lin
引用Jake Lin:
果然是经验之谈,我要细细体会,谢谢!

我觉得MVVM是很复杂的模式,学习成本很高,但是可能维护成本减低。

“ViewModel中不能掺杂任何与界面交互逻辑相关的东西”
请问这个怎么处理?我一般放一些IsLoading,启动动画的依赖属性,用此更新View。

我也发现MVVM有点复杂,一直没有搞清楚,学习成本较高。

  
#28楼 2012-02-02 10:25 | 刘诚楠  
感觉自己也差不多要到这个阶段了,不住的对这些经验点头,哈哈
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
MVC,MVP,MVVM之异曲同工
表现层持续解耦带来的模式转变 MVC MVP MVVM (微软WPF带来的团队变化和软件技...
第1章 MVVM模式介绍及业务应用程序
WPF中MVVM模式原理分析与实践
MVVM模式介绍
智能汽车软硬分离探索和实践分享
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服