说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

谈谈UI架构设计的演化

HTML文档下载 WORD文档下载 PDF文档下载
从经典MVC到MVVM,UI架构经过数次重大变迁,一些概念也在不断变化,架构和底层环境互相影响、适配,时至今日,经典MVC已不再是UI架构的正常选项。本文介绍MVC演进过程,帮大家更好地理解该概念,并指导今后的开发。

【编者按】近日,阿里无线事业部前端工程师寒泉在一篇文章《谈谈UI架构设计的演化》中表示,从经典MVC到MVVM,UI架构经过数次重大变迁。今天无数经过演绎的MVC实现和科普文,要么是原本作者概念已经很混乱,掺杂私货,要么为了适配现代的标记语言和控件模式,自己修改了经典MVC中的一些概念和耦合关系。实际上今天MVC已经没法作为一种交流的标准词汇了。该文从MVC的发展历程着手,对其概念及演进过程进行了肃清,以防开发者被误导。下面为原文。


经典MVC

在1979年,经典MVC模式被提出。

在当时,人们一直试图将纯粹描述思维中的对象与跟计算机环境打交道的代码隔离开来,而Trygve Reenskaug在跟一些人的讨论中,逐渐剥离出一系列的概念,最初是Thing、Model、View、Editor。后来经过讨论定为Model、View和Controller。作者自言“最难搞的就是给这些架构组件起名字”。

因为当时的软件环境跟现在有很大不同,所以经典MVC中的概念很难被现在的工程师理解。比如经典MVC中说:“View永远不应该知道用户输入,比如鼠标操作和按键。”对一个现代的软件工程师来说,这听上去相当不可思议:难道监听事件不需要类似这样的代码吗?

view.onclick = ......

但是想想在70年代末,80年代初,我们并没有操作系统和消息循环,甚至鼠标的光标都需要我们的UI系统来自行绘制,所以我们面对的应该是类似下面的局面:

mouse.onclick = ......mouse.onmove = ......

当鼠标点击事件发生后,我们需要通过View的信息将点击事件派发到正确的View来处理。假如我们面对的是鼠标、键盘驱动这样的底层环境,我们就需要一定的机制和系统来统一处理用户输入并且分配给正确的View或者Model来处理。这样也就不难理解为什么经典MVC中称"Controller是用户和系统之间的链接"。

因为现在的多数环境和UI系统设计思路已经跟1979年完全不同,所以现代一些喜好生搬硬套的"MVC"实现者常常会认为Controller的输入来自View,以至于画出Model、View、Controller之间很奇葩的依赖关系:


我们来看看Trygve Reenskaug自己画的图(这恶趣味的骷髅啊……):


值得一提的是,其实MVC的论文中,还提到了"editor"这个概念。因为没有出现在标题中,所以editor声名不著。MVC论文中推荐Controller想要根据输入修改View时,从View中获取一个叫做editor的临时对象,它也是一种特殊的Controller,它会完成对View和View相关的Model的修改操作。

控件系统

MVC是一种非常有价值的架构思路,然而时代在变迁,随着以windows系为代表的WIMP(window、icon、menu、pointer)风格的应用逐渐成为主流,人们发现,View和Controller某些部件之间的局部性实际上强于Controller内部的局部性。于是一种叫做控件(control)的预制组件开始出现了。

控件本身带有一定的交互功能,从MVC的视角来看,它既包含View,又包含Controller,并且它通过"属性",来把用户输入暴露给Model。

Controller的输入分配功能,则被操作系统提供的各种机制取代:

  • 指针系统:少数DOS时代过来的程序员应该记得,20年前的程序中的“鼠标箭头”实际上是由各个应用自己绘制的,以MVC的视角来看,这应当属于一个"PointerView"的职责范畴。但是20世纪以后,这样的工作基本由操作系统的底层UI系统来实现了。
  • 文本系统:今天我们几乎不需要再去关心文本编辑、选中、拖拽等逻辑,对web程序员可以尝试自己用canvas写一个文本编辑框来体验一下上个时代程序员编写程序的感受。你会发现,选中、插入/覆盖模式切换、换行、退格、双击、拖拽等逻辑异常复杂,经典MVC模式中通常使用TextView和TextEditor配合来完成这样的工作,但是今天几乎找不到需要我们自己处理这些逻辑的场景。
  • 焦点系统:焦点系统通过响应鼠标、tab键等消息来使得控件获得操作系统级唯一的焦点状态,所有的键盘事件通常仅仅会由拥有焦点的控件来响应。在没有焦点系统的时代,操作系统通常是单任务的,但是即使是单一应用,仍然要自己管理多个Controller之间的优先权和覆盖逻辑,焦点系统不但从技术上,也从交互设计的角度规范化了UI的输入响应,而最妙的是,焦点系统是对视觉障碍人士友好的,现在颇多盲人用读屏软件都是强依赖焦点系统的。

所以时至今日,MVC,尤其是其中Controller的功能已经意义不大,若是在控件系统中,再令所有用户输入流经一个Controller则可谓不伦不类、本末倒置。MVVM的提出者,微软架构师John Gossman曾言:“我倾向于认为它(指Controller)只是隐藏到后台了,它仍然存在,但是我们不需要像是1979年那样考虑那么多事情了”

MVP

1996年,Taligent公司的CTO,Mike Potel在一篇论文中提出Model-View-Presenter的概念。

在这个时期,主流的View的概念跟经典MVC中的那个“永远不应该知道用户输入”的View有了很大的差别,它通常指本文中所述的控件,此时在Mike眼中,输入已经是由View获得的了:


Model-View-Presenter是在MVC的基础上,进一步规定了Controller中的一些概念而成的:


对,所以,不论你按照Mike还是Trygve的理解方式,MVP和MVC的依赖关系图应该是一!模!一!样!的!因为Mike的论文里说了“we refer to this kind(指应用程序全局且使用interactor, command以及selection概念的) of controller as a presenter”。presenter它就是一种Controller啊!


把依赖关系画成这样也是醉了啊!不管你信不信我反正是不信啊!

标记语言和MVVM

随着20世纪初web的崛起,HTML跟JS这样标记语言+程序语言的组合模式开始变得令人注目。逐渐推出的Flex、Sliverlight、QT、WPF、JSF、Cocoa等UI系统不约而同地选择了标记语言来描述界面。

在这样的架构中,View(或者说叫控件,不但是从依赖关系上跟程序的其他部件解耦,而且从语言上跟其它部分隔离开来。

标记语言的好处是,它可以由非专业的程序员产生,通过工具或者经过简单培训,一些设计师可以直接产生用标记语言描述的UI。想要突破这个限制使得View跟其它部分异常耦合可能性也更低。

然而这样的系统架构中,MVC和MVP模式已经不能很好地适用了。微软架构师John Gossman在WPF的XAML模式推出的同时,提出了MVVM的概念。

WPF得MVVM正式说明了它的View的概念跟MVC中的View的概念的区别。这里简单画了一下:


在MVVM模式中,数据绑定是最重要的概念,在MVC和MVP中的View和Model的互相通讯,被以双向绑定的方式替代,这进一步把逻辑代码变成了声明模式。

结语

从经典MVC到MVVM,UI架构经过数次重大变迁,一些概念也在不断变化,架构和底层环境互相影响、适配,我认为时至今日,经典MVC已经不再是UI架构的正常选项。

更糟糕的是,今天无数经过演绎的MVC实现(如backbone)和科普文,要么是原本作者概念已经很混乱,掺杂私货,要么为了适配现代的标记语言和控件模式,自己修改了经典MVC中的一些概念和耦合关系。实际上今天MVC已经没法作为一种交流的标准词汇了。

写此文,希望大家能了解些历史上的发展历程,莫被不严谨的文章误导。(责编:陈秋歌)

原文来自:寒泉的微博文章

用鼠标拖动无标题窗口-Delphi资料 在Delphi编程中创建一个启动闪现窗口 在form中想用enter来代替tab,请问如何实现?-Delphi资料 在Listboxes中加背景图-Delphi资料 在Window右下角的添加图标-Delphi资料 在程序中使用自定义的鼠标-Delphi资料 怎样建立简单的任务栏应用程序-Delphi资料 增强DelphiTStatusBar控制 制作Delphi的竖排标签 自适应表单的实现-Delphi资料 COM/DCOM的区别与联系-Delphi资料 CoolBar上控件的排列顺序-Delphi资料 Delphi 4 WebBroker Delphi 中自做动态显示的控件 Delphi3的DBGrid中的下拉列表和查找字段编程方法 DELPHI常见问题 Delphi的竖排标签 DELPHI构件制作方法 DELPHI控件Tweblabel的编制 DELPHI中MEMO组件的光标定位 Delphi中RichEdit的奥妙 Delphi中TApplication类 Delphi中日期时间输入的简洁方法 delphi中怎么调用interbase数据库? Memo的Undo功能-Delphi资料 RECT在Delphi中的灵活使用 StringGrid制作只读列-Delphi资料 TADOQuery下主明细表其属性关系如何设置,如何保存主表和明细表?-Delphi资料 TBatchMove用法-Delphi资料 TMemo的真正插入字符-Delphi资料 TREEVIEW的使用-Delphi资料 今天下午有没有去微软发布会的????马上回答 关于字体问题!请教会者不难者!!!!!!!! 請問怎麼定義小一點得符點數???? ReadFile超时返回什么? 我的机器装了2000server,2000profession 和NT4.0,现在机器空间不够想把nt4.0和2000profession 卸载,请问应该如何进行?? 怎样用PB代码实现在MDI窗口里的 Ctrl + Tab 的功能 ? 如何将静态库加入项目中,有头文件,SETING出也加入,为何说和系统的库重复定义 如何调用非mfc的程序调用mfc下开发的动态连接库, 请问谁有监测图片变化的部分代码?(在线等待) GetCurrentDirectory()?? 用ADo更新图片(bmp,jpg)难道只能将原来的数据记录删除后在添加吗?不能直接更新吗? 请大家帮忙解决一下循环体的问题!!:) 请问oracle 自己带的http server(实际上是apache)如何配置class path 给你100分(OLE) 我在制作一个网络浏览器时遇到一个问题,在线等你的帮助 公司不做软件了,失业了,高兴送分 JNI 中内存管理的问题 ehlib控件的问题,如何在表中的一字段显示一个列表?分可以加,,,在线等 大家帮我 c# 的一大难题? 一定加分! 十万火急~~谁有完整的网站计划书? 能不能给我一份,万分感谢! 高分求教不用ActiveSkin实现金山词霸类窗体和按钮效果。 用delphi编写的dll结果不能调用,谢谢你的回答!!! mscomm控件读写串口的问题 正式加入水园 请教ListView控件的使用。 这里有100分(OLE) 公司不做软件了,失业了,高兴送分 请问,哪有oracle express object 的使用指南下载呀。 急~~~~~~哪里可以找到完整的网站计划书? 告诉我下载地址也可以,非常感谢!!! 急!!!怎样用VBA写一句话,判断word是不是当前活动窗口? CMainFrame::PreCreateWindow(CREATESTRUCT& cs) 的cs.lpszClass内容的不能改变 想了解下深圳的程序元的人工如何??请深圳的朋友介绍下好么?听说一般的都有6K~7K,是不是啊?? 插入表单的问题 SilverStream研讨会及中国CTO李渊明给人的印象 如何打印datawindow,操作如下:对同一个datawindow连续打印,但是每次打印都是不同的数据,espon1600K-III w_mainps.sqlinfo() 这个sqlinfo()可能是什么呢? 安装程序的问题 高分求购: MP3歌词协议 SAMI 小问题 现在163.net 163.com的 smtp服务都需要验证,如何在VB中实现验证才能发出邮件? 女人如何合理利用蟑螂(转) 开发游戏的时候,人物造型是怎么做出来的,3dmax里面吗?就是说人体数据和衣服数据是分开来的? 一个IDL文件的编译问题 请帮个小忙 如何编码实现工作流控制的自动化?(比如VC) vector 分配的内存怎么释放 bcb6 中的 FASTREPORT 的问题,100分送上 ASP中应用Excel遇到的问题 捕捉缓冲区的错误…………,相当急! ???SQL Server VS Windows 98,让我欢喜让我忧。哪位大虾帮我解忧愁??? 水里加几勺盐就能把鸡蛋浮起来 空气的成分是什么? 铜,铁,铝的导热性谁最好? 下列加入盐酸,溶液的PH值不会改变的是( ) a.Zn b.AgNO3 c.Na2CO3 d.NaOH 氯化铁与碳酸钠反应的方程式?还有氯化铁与碳酸氢钠反应的方程式? 人呼吸出的空气的成分【呼出的,要化学式和中文】 下列物质加入稀盐酸中,溶液的PH不会明显改变的是:A AgNO3 B Fe C CuO D NaOH 碳酸钠,氯化铁水解方程式 我们靠什么呼吸 自行车行驶时前后轮的摩擦力方向? 我测盐酸的PH值时为什么是负的是1:3的盐酸 我们常吃的鸡蛋也经常呼吸,一个鸡蛋上有( )个呼吸小眼供它呼吸.A 700左右B 7000左右C 70000左右 在稀盐酸中加入下列物质,溶液的PH值几乎不变的是A.AGNO3B.CACO3.C.KOH.D.CAO 纯盐酸的PH值是多少? 为什么我们人类会呼吸 在稀盐酸中加入下列物质,溶液的ph变化最小的是:AgNO3固体 CaCO3固体,KOH固体,生石灰 在蒸馏水中加下列物质,所得溶液PH值明显升高 A盐酸 B二氧化碳 C二氧化硫D生石灰 为什么SO2不能被生石灰干燥? 用手将一重为5N的物体全部压入水中,物体排开的水重8N,此时物体受到的浮力为 N,用手将一重为5N的物体全部压入水中,物体排开的水重8N,此时物体受到的浮力为N,放手后物体将(选填”“上浮 在稀盐酸加入下列什么物质,溶液PH几乎不变 A.生石灰 B.Caco3 C. koH D . AgNO3 碳酸钠与氯化铁反应 把重5N,体积为0.6dm3 的物体投入水中,若不计阻力,当物体静止时受到的浮力多大 用于检验二氧化碳的实验方法是什么?检验氧气的实验方法是什么?证明水蒸气存在的方法是什么? 碳酸钠和氯化铁反应的现象将碳酸钠溶液放入氯化铁溶液中会出现什么现象呢? 塑料热成型加工的特点有哪些? 碳酸钙不溶于水,为何有碳酸钙溶液的说法,如果有,碳酸钙溶液的PH为多少拜托了各位 哪些盐溶液的PH不是7的,水解是怎么回事 室温时,将xmLpH=a的稀NaOH溶液与ymLpH=b的稀盐酸充分反应.下列关于反应后溶液pH的判断,正确的是有这几个答案A.若x=y,且a+b=14,则pH>7 B.若10x=y,且a+b=13,则pH=7C.若ax=by,且a+b=13, 什么叫金属冷挤压模具和热挤压模具? 什么是等熵效率 向稀盐酸中加入NaOH溶液,溶液的pH会改变吗? 挤压成形、车制、压铸、冲压、机压这5种工艺的特点是什么?麻烦给出相应类型的材料举例.挤压成形、车制、压铸、冲压、机压这5种工艺的特点是什么?麻烦给出相应类型的材料举例.不同类 条件熵的计算步骤一定要举例说明啊,可以追加分的哟!帮我算一下下面图中的条件熵,这个表是判断气象的知识表达系统。论域U由14个气象状态组成,属性有五个,其中包含4个条件属性,分 什么是等熵压缩?什么是低熵压缩?有没有负熵压缩?各代表什么物理含义?此外熵究竟如何理解?如何定义的?请不要在网上复制一大堆没用的,简单明了一点吧. 铝合金2A50,怎样判断该用冷挤压?还是热挤压?根据 变形程度 那么 变形范围是多少呢? 计算呼吸熵生物呼吸作用的底物(有机物)种类及含量的差异,会导致呼吸作用释放的CO2与吸收的O2比发生差异,这可用呼吸熵表示:呼吸熵(RQ)=呼吸作用释放的CO2/呼吸作用吸收的O2,为了测 等熵压缩的定义 一块实心铁球浸没在水中时,受到的浮力为19.6牛求铁块的体积 熵里面的这个是什么啊 怎么算的= = 怎么算啊? 空气的成分是/?初三化学 把体积是100的实心铁块浸没在水中,铁块受到的浮力多少牛(g取10牛/千克)(铁的密度=7,9X10千克/米) 关于熵的计算热机工作于600K和300K的两个热源之间,在一次循环中从高温热源吸热4000J.(1)若该热机为一可逆的卡诺机,每经过一个循环两热源及热机组成系统熵变化了多少?(2)若某热机的循 氯化铁与碳酸钠反应吗若反应写出化学方程式 若不反应说明理由 设计实验证明:我们呼出的气体中含有大量的水蒸气 空气中的水蒸气是由______形成的 求氯化铁和碳酸钠反应的方程式 在PH=1的溶液中有NaCl、Na2CO3 Na2SO4,分析说他们氢离子和碳酸根会生成水和二氧化碳,哪里来的氢离子啊以上三种化学式都没有氢离子啊,为什么说他们氢离子和碳酸根反应呢、?那个氢离子哪来的 有没有等温过程或绝热过程的生活物理应用? 一定量理想气体分别在恒压和恒容下,从T1到T2,.如何证明恒压的熵变是恒容的n倍 均匀蜡烛长20CM密度为0.8×10^3kg/m3,下面粘一小铁块,竖直浮于水面上,上端露出水面1cm,然后点燃1、均匀蜡烛长20CM密度为0.8×10^3kg/m3,下面粘一小铁块,竖直浮于水面上,上端露出水面1cm,然后点燃蜡 水中物体有不受浮力的时候吗 初中物理怎么判断浮力大小 哪种水最好喝?大神们帮帮忙 今天大学物理课 老师一道题想不通 绝热膨胀为什么会等温的 铁的导热性好还是差? 被辣到了,怎么办呢? 将装有水的杯子放入水槽中,则杯子所受的浮力怎么求? 新鲜鸡蛋在水中加盐会浮起来,加糖会怎样呢?如题⊙﹏⊙b汗, 为什么鸡蛋在一只装满水的桶里加很多盐会浮起来? 在一个杯子里装满水把一个球放进去与杯底相贴就是说不受浮力,请问水对球向上的浮力以及球对杯底的压力用公式表示就可以了球就是与杯底无缝接触.不受浮力,要求的是水对球向下的力 铁和大理石哪个导热性强
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘