这篇文章不会说 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. Restore IP Addresses,将字符串转换成ip地址

    问题描述: Given a string containing only digits, restore it by returning all possible valid IP address c ...

  2. Bigdecimal: Non-terminating decimal expansion; no exact representable decimal result.

    做除法没有指定保留小数点后几位,就会抛出此异常. 因为会除不尽 Non-terminating decimal expansion; no exact representable decimal re ...

  3. 欢迎来到 Flask 的世界

    欢迎来到 Flask 的世界 欢迎阅读 Flask 的文档.本文档分成几个部分,我推荐您先读 < 安装 >,然后读< 快速上手 >.< 教程 > 比快速上手文档更详 ...

  4. 优先队列PriorityQueue实现 大小根堆 解决top k 问题

    转载:https://www.cnblogs.com/lifegoesonitself/p/3391741.html PriorityQueue是从JDK1.5开始提供的新的数据结构接口,它是一种基于 ...

  5. python 重新修炼之路

    第一篇 基础篇 1.1  打造万能的开发环境-conda  1.2   python的代码规范与vscode配置   1.3 变量 与 关键字   1.4 数据类型     1.4.1 数字      ...

  6. bzoj2929

    题解: 网络流裸题 代码: #include<cstdio> #include<cstring> #include<algorithm> #include<c ...

  7. PIVOT 和 UNPIVOT 命令的SQL Server版本

    I:使用 PIVOT 和 UNPIVOT 命令的SQL Server版本要求 1.数据库的最低版本要求为 SQL Server 2005 或 更高 2.必须将数据库的兼容级别设置为 90 或 更高 3 ...

  8. qml 与C++交互

    最近一直在研究qml 怎么与C++交互,今天在网上看到一段代码忽然想明白了,哦!!!我在QT还只是一个小白,嘿嘿 首先在我们定义了CPP文件起名:比如:util.cpp,baidumusic.cpp ...

  9. 平衡二叉树(AVL)的实现,附可运行C语言代码

    最近几月一直在自学C语言和数据结构,先是写了排序二叉树,觉得平衡二叉树作为一个经典数据结构,有必要实现一下. 网上看了些资料,在AVL和红黑树之间考虑,最后个人还是倾向于AVL. 不同于标准AVL的是 ...

  10. New Concept English three(13)

    1原文打字 32w/m 错词27个 After her husband had gone to work, Mrs Richards sent her children to school and w ...