MVVM(Model-View-ViewModel)介绍

8.1 分离用户界面和业务逻辑

在开发应用程序时,要把用户界面和业务逻辑分离开来,这是每个程序员都知道的常识。分离用户界面和业务逻辑有几个重要的好处:

  1. 有利于隔离变化。用户界面是最容易变化的,易用性的改进,外观的美化和需求的变化,首先冲击的就是用户界面。如果用户界面和业务逻辑耦合到一起,界面上一点微小的改动都会导致一系列代码的修改,这不但会增加开发的成本和周期,而且这种改进也是很无趣的,让程序员的幸福感直线下降。
  2. 有利于自动测试。代码中的BUG,越早被发现,修改的成本越低,而单元测试是在早期发现BUG的重要手段。单元测试是自动化的,前期编写测试代码的投入,会因为后期节省测试的时间而获得回报。单元测试代码可以不断积累,为软件构建一道坚固的防火墙,让整个系统越来越稳定。分离用户界面和业务逻辑是提高代码可测试性的重要手段,让编写单元测试程序成为可能。
  3. 有利于分工合作。用户界面和业务逻辑的耦合,会让用户界面的修改很困难,程序员就会抵触用户界面的改动,让设计师和程序员之间的矛盾加大。分离用户界面和业务逻辑后,设计师的工作成果可以平滑的输出给程序员,让程序员和设计师一起过上共同幸福的生活。

8.2 如何分离用户界面和业务逻辑

分离用户界面和业务逻辑,MVVM是目前最常用的模式。MVVM并非凭空出现,而是由MVC和MVP一路演化而来的,每次演化都是为了解决之前没有解决的问题。

8.2.1 MVC模式

MVC是Model-View-Controller简称,它首次把系统分成Model,View和Controller这三部分,明确的把用户界面和业务逻辑分离开来:

  • 模型(Model)。简单的说,模型就是业务逻辑。我们经常说面向对象的设计和建模,所建立的模型就是这里的模型,是对现实世界中业务逻辑的抽象。面向对象的建模,就是要找到业务逻辑中有哪些类以及这些类之间的关系。类描述了对象的属性和行为,类是设计时的概念,对象是运行时的概念。对象通常就是业务实体,Model包含一个或多个业务实体。很多人(包括国内一些知名的专家)认为模型就是数据,这是没有透彻理解面向对象的设计导致的,对象是即有数据又有行为的,光有数据没有行为,就无法让对象之间协作,无法共同完成业务逻辑。
  • 视图(View)。这个是大家都知道的,就是用户与软件交互的界面,对于GUI应用程序来讲,就是窗口和对话框,以及上面的各种控件。视图应该说是为用户提供了一个界面,让用户可以观察和操作模型。
  • 控制器(Controller)。控制器负责解释来自用户通过键盘/鼠标等设备的输入,并通知模型和视图做出相应的改变。在GUI应用程序中,直白的说,其实就是控件的事件处理函数,它与界面相关和模型都相关,它从界面获取数据,然后调用模型的函数,有时还会直接更新用户界面。

控制器(Controller)不是业务逻辑,理论上只是很薄的一个胶合层,但是很多新手把业务逻辑写在控制器里,导致模型只剩下数据了,让人产生控制器就是业务逻辑,模型就是数据的错觉。

8.2.2 MVP模式

MVC模式解决分离用户界面和业务逻辑的问题,但是还有一个重要的问题没有解决: 控制器是界面相关的,没有办法为控制器编写单元测试程序。为了解决上面的问题,MVP模式应运而生。MVP是Model-View-Presenter简称。

  • 模型(Model)。模型还是MVC中的模型,这里不再赘述。
  • 视图(View)。视图还是MVC中的视图,但它不需要向模型注册改变的事件通知了,这个由呈现逻辑去做了。
  • 呈现逻辑(Presenter)。Controller变成了Presenter只是表面现象,最重要的是MVP对视图进行了抽象,呈现逻辑不再向控制器那样直接访问具体的视图了,而是通过视图的接口去访问视图,视图的接口是抽象的,可以有不同的实现,所以可以方便的Mock出一个视图,让编写呈现逻辑的单元测试程序成为可能。注意,这里视图的接口并不是通用的,每个视图都有一个独立的接口,有一个真正的实现和一个用于测试Mock的实现。

从理论上讲,MVP模式已经很完备了,它很好的分离的界面和实现,也可以为呈现逻辑编写单元测试程序了。但是从工程角度来看,MVP却有一个非常致命的缺陷:要编写大量无聊的代码!

为了方便说明,我们以一个编辑图书信息例子,看看要写哪些无聊的代码。这个例子非常简单,却要写不少无聊的代码:

  • 1.初始化的时候,要为控件注册事件处理函数,比如为『保存』按钮注册事件处理函数。
  • 2.初始化的时候,要把图书信息,如书名、作者和出版社等信息从模型中取出来,一个一个的设置到视图的控件中去,在这个过程中,可能需要对数据格式进行转换,比如出版日期,在模型中是一个整数,在视图上表现为一个字符串,这就需要转换。
  • 3.在编辑结束时,要从视图中把图书信息,如书名、作者和出版社等信息一个一个的取出来,再保存到模型中去。在这个过程中,可能需要对数据格式进行转换,比如前面的出版日期,要把视图中的字符串转换回模型中的整数。
  • 4.View都有一个接口定义,有一个真正的实现和一个Mock的实现。

这些代码很简单却很无聊,在每个有界面的模块中,都遵循同样的规律,却又完全不同,不得不重新编写。

8.2.3.MVVM模式

把MVP模式这些规律找出来进行抽象,通过一些规则在视图和模型建立联系,也就是数据绑定和命令绑定,就形成了MVVM模式。MVVM是Model-View-ViewModel简称。在MVVM中:

  • 模型(Model)。模型还是MVC中的模型,这里不再赘述。
  • 视图(View)。视图还是MVC中的视图,但它不需要向模型注册改变的事件通知了,这个由数据绑定去做了。
  • 视图模型(ViewModel)。 ViewModel不是Controller也不是Presenter,视图模型是视图还是模型?按MVVM的发明者John Gossman的话说,视图模型是视图眼中的模型。放大镜下的虫子还是虫子,所以视图眼中的模型还是模型。视图模型与视图没有直接关系,是可以为之编写单元测试的。

呈现逻辑Presenter去哪里了?呈现逻辑从一行行代码变成了一条条数据绑定和命令绑定的规则,对规则的处理和解释成了MVVM框架或公用库,可以在多个项目中共享。

MVVM模式有下列好处:

  • 强制分离用户界面和业务逻辑。在MVC和MVP中,不能强制分离用户界面和业务逻辑,程序员的一念之间,就导致用户界面和业务逻辑混在一起。MVVM中不需要编写界面相关的代码,自然没有办法让用户界面和业务逻辑耦合到一起。
  • 界面描述文件和程序代码之间具有更松的耦合。通常用XML或RC文件来描述界面,在MVC和MVP中,在界面上增加一个控件或删除一个控件,都会导致相应的代码需要修改。而在MVVM中,采用了面向意图的编程,界面上表现的只是一种意图,至于在程序中,谁去实现,怎么实现,甚至有没有实现,界面都是不关心的,所以界面和代码之间值的耦合是很松的。
  • 不需要学习GUI的API。通过数据绑定和命令绑定建立视图和模型之间的联系。用声明式的规则取代命令式的代码,不需要写界面相关的代码,所以不需要学习GUI的API,无论是采用Qt还是AWTK,都用同样的方式开发。

视图模型和模型并不相同,之所以要引入视图模型,主要原因有:

  • 模型中的数据有时并不适合直接显示在视图上。比如出版日期,在模型中是整数,直接显示出来,用户就看不懂,需要转换成人类可以理解的字符串。
  • 模型中的一个数据项可能以多种形式呈现在视图上。比如出版日期,除了显示出版日期外,也可能把最近出版的书,显示一个新书标志。
  • 视图中的输入数据和模型中的存储数据,它们的格式有时可能不同。比如出版日期,视图上输入的格式和模型里存储的格式就不一样。
  • 视图需要视图模型提供数据校验规则来判断视图上的输入是否合法。
  • 有些数据是有依赖关系的。比如在输入收货地址时,选择省份时,城市列表跟着变化。
  • 有些状态不属于业务逻辑,但是需要保存下来。如为了支持撤销操作,需要保存命令历史记录。
  • 在C/C++等静态语言中,没有办法通过函数的名称去调用对象的成员函数,也没有办法通过属性的名称去访问对象的成员变量。视图模型需要提供一种机制来实现这些功能,否则绑定规则就没法实现。

MVVM 的缺点。

  • 内存问题。据说WPF内存开销很大,即使在PC上也大得让人无法忍受(常有人借此来反对MVVM)。WEB前端流行的MVVM框架,像React和Vue.js等,采用虚拟DOM的方式,内存需求可能有大幅度增加。
  • 性能问题。MVVM通常的做法是,模型有变化时会刷新整个界面。如果采用虚拟DOM的方式,还需要重新构建一个虚拟DOM,与原来的虚拟DOM比较,性能开销就更大了。
  • 调试问题。如果没有工具的协助,数据绑定会让调试变得困难。

以上这些问题在手机和PC上,已经不是什么大问题了,但对于嵌入式系统来说,仍然是难以跨越的障碍,所以目前几乎没有针对嵌入式平台开发的MVVM框架。

8.3 AWTK-MVVM

AWTK-MVVM是一套用C语言开发的,专门为嵌入式平台优化的MVVM框架。它实现了数据绑定、命令绑定和窗口导航等基本功能,使用AWTK-MVVM开发应用程序,无需学习AWTK本身的API,只需学习绑定规则和模型的实现方式即可。

与其它MVVM框架相比,AWTK-MVVM特点有:

  • 代码小。

    • 核心代码:约3000行。
    • AWTK相关代码:约700行。
    • jerryscript相关代码(可选):约1700行。
  • 性能高。核心代码用C语言开发,其性能与直接使用AWTK差别不大。
  • 内存开销小。
    • 一条绑定规则大概需要150字节。一个窗口上若有10条绑定规则,内存占用了也就1.5K。
    • 列表中的绑定规则可以共享,额外增加的内存开销,比例也是很小的。
  • 隔离更彻底。在AWTK-MVVM中,界面和绑定规则在XML中描述,开发应用程序时只需要开发模型(也就是业务逻辑)即可。除非通过特殊手段,开发者没有机会直接去访问视图。
  • 易调试。
    • 提供视图模型的框架生成工具,避免手写代码造成的错误。
    • 增加了各种异常处理的LOG信息。
    • 提供大量的demo以供参考。
    • 开放源码,调试方便。
  • 支持多语言开发。

    • 目前支持C语言和JS。
    • 以后会根据需要支持新的编程语言。

这里支持的多种编程语言与AWTK的脚本绑定是完全不相关的概念:这里是让应用程序的业务逻辑可以用不同的语言来开发,而AWTK的脚本绑定是让应用程序可以使用不同的脚本语言来调用AWTK的API。

  • 可移植到其它GUI。AWTK-MVVM是为AWTK设计的,但是我们隔离了与AWTK相关的代码,让它可以移植到其它GUI。AWTK相关的代码仅仅700来行,可见移植到新的GUI是非常容易的事情。当然,AWTK可以满足常见的需要,这样做只是给开发者提供更多选择。

AWTK-MVVM也有些限制,目前不支持界面元素动态生成,这时可以结合传统的方法开发。以后AWTK会支持WEB前端流行的框架如Reactjs和Vuejs,在高端平台(如手机、小程序和桌面程序)中应用。

在后面的章节中,我们将详细介绍AWTK-MVVM的具体用法。

c# mvvm模式获取当前窗口_AWTK-MVVM 介绍相关推荐

  1. c# mvvm模式获取当前窗口_对Vue中的MVVM原理解析和实现

    首先你对Vue需要有一定的了解,知道MVVM.这样才能更有助于你顺利的完成下面原理的阅读学习和编写 下面由我阿巴阿巴的详细走一遍Vue中MVVM原理的实现,这篇文章大家可以学习到: 1.Vue数据双向 ...

  2. c# mvvm模式获取当前窗口_【自学C#】I 书 12 异常处理

    一.简介 如果程序做得不是很完善,比如一个接收数字的文本框,输入了字母或中文,将会弹出错误并中断程序. 本章将讨论如何处理这些问题,从而使得应用程序变得更加完善. C#异常处理功能提供了处理程序运行时 ...

  3. WPF随笔(十四)--如何在MVVM模式下关闭窗口

    离上一篇WPF随笔有多久,再度编码WPF项目就有多久.机缘巧合又接下了一个开发WPF桌面程序的任务,又有机会详细研究之前一直忽略的细节. 今天就来谈谈如何在MVVM模式下关闭窗口. 什么?关闭窗口还要 ...

  4. C# WPF MVVM模式下在主窗体显示子窗体并获取结果

    01 - 前言 在winform中打开一个新的子窗体很简单,直接实例化窗体并show一下就可以: Form2 f2 = new Form2();f2.Show(); 或者 Form2 f2 = new ...

  5. C# WPF MVVM模式Prism框架从零搭建(经典)

    01 - 前言 目前最新的PRISM的版本是8.1.97,本节以6.3.0.0 讲解,可以在Github上获取PRISM的源码. Prism Github地址:https://github.com/P ...

  6. C# 浅谈基于Wpf下的MVVM模式的设计思想

    目录 一.Model实体层 二.ViewModel视图模型层 1.定义属性通知基类 1.1 数据验证接口的实现 1.2 验证标识类定义 2.ViewModel前端交互实现 2.1 ICommand命令 ...

  7. Android MVC,MVP,MVVM模式入门——重构登陆注册功能

    一  MVC模式: M:model,业务逻辑 V:view,对应布局文件 C:Controllor,对应Activity 项目框架: 代码部分: layout文件(适用于MVC和MVP两个Demo): ...

  8. iOS进阶之架构设计MVVM模式仿新闻项目(6)

    这是MVVM的第三篇文章了,之所以花这么多文章来介绍MVVM,就是为了加深对MVVM的理解,以及从不同demo的角度,对比分析那种是最适合自己的模式. 转自文章 iOS使用MVVM模式仿新闻项目 一. ...

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

    WPF MVVM从入门到精通1:MVVM模式简介 原文:WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录 ...

最新文章

  1. Nginx配置文件nginx.conf中文详解(转)
  2. 清华校庆正当时,智能小车决赛日
  3. Java 时间 Date类型,Long类型,String类型
  4. 贪吃蛇原型实现基本思路
  5. 安装Sublime Text 支持Go插件
  6. asp中正则表达式应用
  7. SAP UI5 oSelectedItem.getBindingContext(json)
  8. java 实现压缩单个文件
  9. 安装vsphere update manager及注意事项
  10. 跟着图灵去听课——海底捞敏捷之道纪要
  11. Java宣言的时候,JAVA面向对象-对象宣言
  12. Tiny服务的开发配套的工具来了
  13. ESP-Tuning Tool 使用手册
  14. 锂电池容量电压对照表_商业化磷酸铁锂电池PK三元锂电池 谁更胜一筹?
  15. el-select 远程搜索时 没有箭头图标
  16. 虚拟服务器的常用服务器选什么,如何选择合适的虚拟主机,虚拟主机选什么系统...
  17. python积木编程软件_童心制物慧编程全新 Python 编辑器正式上线
  18. Hadoop的完全分布式搭建
  19. ORACLE表格操作图文教学二(分组去重、计数、加减、多表)
  20. XXX旅游公司建立旅游胜地电子商务网站招标书

热门文章

  1. python3-matplotlib基本使用(以折线图为例)
  2. yii2 mysql in_yii2 mysql数据库读写分离配置
  3. html5怎么自动生成meta标签,html中meta标签该如何使用
  4. java foreach并行_使用foreach在Java中迭代并行数组的漂亮方法
  5. qt不规则按钮样式在自适应分辨率时应该注意的图片缩放模式
  6. C语言 文件读写 fputc 函数 - C语言零基础入门教程
  7. C语言 野指针 - C语言零基础入门教程
  8. java游戏可以刷升级挖药材,【毕业设计】Java手机游戏设计
  9. 已达成计算机的连接数最大值无法再,已达到计算机的连接数最大值,无法再同此远程计算机连接...
  10. 爱尔兰都柏林圣三一大学计算机排名,2021年爱尔兰都柏林圣三一大学世界及专业排名 不愧是最古老的学府!...