这篇文章不会说 MVVM 是什么,因为讲这个的文章太多了;也不会说 MVVM 的好处,因为这样的文章也是一搜一大把。我只是想说说我们究竟应该如何理解 M-V-VM,当我们真正开始写代码时,应该在里面的每一层里写些什么。


MVVM,当然三层——M-V-VM。就凭这个“三层”结构,WPF/UWP 开发者们就能折腾出一个完整的程序出来。M——定义数据模型啊,V——视图啊,VM——视图模型。其中 M 和 V 的中文词语和英文单词是很好理解的,但是 VM 就不是个日常用词;于是各种不知道应该放在哪里的代码便一窝蜂全放进了 VM 中,最终导致了 VM 的无限膨胀,成百上千行也是司空见惯啊!

可是,若 VM 不膨胀,那让 M 或者 V 膨胀吗?当然不是,谁都不要膨胀!于是那么多的代码写到哪里呢?

答案:MVVM 之外

 

我们的代码不止 MVVM 三层

MVVM 不是应用程序架构,只是一个 GUI 类程序的开发模式而已。这意味着它只是用来解决我们应用程序中 GUI 部分的开发问题,并不能用来解决其他问题。而一个能持续发展的程序怎么能只有 GUI 呢?

  • MVVM 只是数据驱动型 GUI 程序建议的开发模式;无论是三层中的哪一层,本质上都是在解决 UI 问题。
    而非 UI 问题根本就不在 MVVM 的讨论之列。

不知看到这里时你会不会喷我一脸——“V”解决 UI 问题也就算了,“VM”和“M”算什么 UI!

VM,视图模型。其本质是模型。什么的模型?“视图”的模型。这是为真实的 UI 做的一层抽象模型。也就是说,VM 其实是“抽象的 UI”。

接着喷——“V”和“VM”解决 UI 问题也就算了,“M”算什么 UI!

M,数据模型。作为数据驱动型 GUI 程序,这些数据是用于驱动 UI 的数据;比如网络请求的数据,本地文件储存的数据。定义这些数据模型是为了与其他组件、其他程序、其他设备传递数据,并将这些数据为视图模型所用。那些不驱动 UI 的数据根本不在此谈论之列。如果你觉得这样的解释有些牵强,那我也无话可说;但是当我们将它理解成“驱动 UI 的数据”时,我们将能够更容易地组织我们的代码,使之不容易发生混乱。

MVVM 模式按此理解后,我们将更能够将代码放到合适的位置,避免 VM 代码的膨胀:

  1. 公共的控件或者辅助代码应该抽出来放到别处,比如形成公共组件
  2. 一些非 UI 的业务功能单独做,独立于 MVVM 模式,对 VM 提供调用接口即可。

MVVM,应该做什么,不应该做什么

这一节内容部分参考自:MVVM standardization - W3Cgeek

View

  1. 想进行测试的逻辑都不要放到这里
  2. 不止能是 Window/Page/UserControl,还能是 Control/DataTemplate
  3. 可以考虑使用 DataTriggerValueConverterVisualState 或者 Blend 中提供的 Behivor 机制来处理 ViewModel 对应的 UI 展现方式

ViewModel

  1. 这里需要保持抽象 UI 的状态,这样才可以在据此 ViewModel 创建多个 View 的时候,这些 View 能够完全一致而不用把此前逻辑再跑一边
  2. 无论如何都不能引用 View,就算是接口也不行
  3. 注意不要去调用一些单例类或者带状态的静态类,这样才好进行单元测试

Model

  1. 那些通过各种途径搜罗来的数据
  2. 不能引用 View,也不能引用 ViewModel

View 通知 ViewModel

  1. 推荐用数据绑定
  2. 尽量不要直接调用 ViewModel,但必要的时候也可以去调用

ViewModel 通知 View

  1. 属性绑定
  2. 事件通知
  3. 消息(比如 EventAggregator/Message/RX 框架)
  4. 通过中间服务调用
  5. 直接由 View 传入一个委托,ViewModel 去调用那个委托

参考资料

当我们使用 MVVM 模式时,我们究竟在每一层里做些什么?的更多相关文章

  1. Prism 4 文档 ---第5章 实现MVVM模式

        MVVM模式有助于清楚的区分应用程序界面的业务层和展现层.保持一个清晰的应用程序逻辑和UI分离有助于处理开发和设计过程中大量的问题,同时,使得应用程序的测试,维护,和扩展更加容易.MVVM也可 ...

  2. WPF MVVM从入门到精通1:MVVM模式简介

    原文:WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录窗口 WPF MVVM从入门到精通3:数据绑定 W ...

  3. MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息

    MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二 ...

  4. MVVM模式解析和在WPF中的实现(五)View和ViewModel的通信

    MVVM模式解析和在WPF中的实现(五) View和ViewModel的通信 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 M ...

  5. MVVM模式解析和在WPF中的实现(三)命令绑定

    MVVM模式解析和在WPF中的实现(三) 命令绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  6. MVVM模式和在WPF中的实现(二)数据绑定

    MVVM模式解析和在WPF中的实现(二) 数据绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  7. MVVM模式和在WPF中的实现(一)MVVM模式简介

    MVVM模式解析和在WPF中的实现(一) MVVM模式简介 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在 ...

  8. dynamic-css 动态 CSS 库,使得你可以借助 MVVM 模式动态生成和更新 css,从 js 事件和 css 选择器的苦海中脱离出来

    dynamic-css 使得你可以借助 MVVM 模式动态生成和更新 css,从而将本插件到来之前,打散.嵌套在 js 中的修改样式的代码剥离出来.比如你要做元素跟随鼠标移动,或者根据滚动条位置的变化 ...

  9. 由项目浅谈JS中MVVM模式

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.    背景 最近项目原因使用了durandal.js和knock ...

随机推荐

  1. 安装 inotify-tools

    摘要 inotify-tools, 是一款google出的用于监控文件系统的软件. 一.软件下载地址官方站点地址:http://inotify-tools.sourceforge.net/仓库地址:h ...

  2. mysql的基本的数据库的查询

    学习一个数据库我们要学习哪些东西: sql数据库的话, curd. 对于查询,要注意表的关联的查询. 索引,触发器,对于控制连接量,脚本, 数据库的可视化工具,权限管理. http://www.360 ...

  3. 1-26-1-expect无交互式-正则表达式

    大纲: 1.expect环境搭建及脚本编写 概述 expect脚本详解 expect环境搭建 expect脚本实现ssh远程连接 expect脚本实现ssh远程连接(通过shell传递参数) 2.正则 ...

  4. 【转】 JavaScript:history.go() 的妙用(转) 处理post回发后返回

    在Web开发中,会遇到从一页(父页)导向另一页(子页),并且要求“返回”父页的情况,在这里如果用ASP.NET提供的 Response.Redirect()方法,往往不会达到理想的效果,例如:返回后, ...

  5. 032——VUE中表单控件处理之复选框的处理

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. vue创建组件

    vue创建组件是很容易的: js: Vue.component("component-item",{   //component-item就是我们在HTML页面上引用的组件,它会在 ...

  7. hdu 6058 Kanade's sum(模拟链表)

    Kanade's sum Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

  8. EasyUI Combobox 组合框

    默认选择第一项,加请选择,取值问题 <input class="easyui-combobox" id="ddlWHS" name="ddlWH ...

  9. 12.18 微信扫码获取openid与登陆

    官方文档: https://open.weixin.qq.com/ 1.先获取code 1-1 配置项目配置文件 wechat: mpAppId: wxd898fcb01713c658 mpAppSe ...

  10. TableviewCell嵌套TextView自动换行

    TableviewCell嵌套TextView自动换行 欢迎到github上去下载源码Demo, github链接:https://github.com/mengzhihun6 效果图: