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

谈谈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已经没法作为一种交流的标准词汇了。

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

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

谁能成为Hero,这一次你说了算!——TCL智能电视开发大赛创意阶段评审征集 微信官方在“公开课”上13个热点问题的解答摘要 MDCC 2014移动开发者大会10月开幕:你就是主角! 设计师该如何挣得一席之地? 回到未来:最热门的十大清洁能源技术公司 深度学习:未来机器人的进化途径 搜狗开源内部项目管理系统Cynthia,已被数十家企业采用 沃游戏新版本全新登场 好友PK根本停不下来 腾讯发布首款智能硬件,内部筹建孵化器鼓励创新 触控开发者平台:孕育“十亿开发者俱乐部” 《近匠》大新伙伴:大姨吗防晒小助手,帮你呵护女神 专访阿里云总裁王文斌:做出“用得爽”的工程产品 专访AMD全球副总裁潘晓明:2014全线发力,力争中国市场 搜狗开源内部项目管理平台Cynthia意欲何为? 深度解析浪潮新八路服务器TS860 支持Box2D,开源HTML5 2D游戏引擎FLAG 一周消息树:从程序员到架构师的方法与逻辑 【CTO俱乐部走进海尔】海尔的转型探索之路 十一问MongoDB CTO,谈NoSQL人气王的扩展、事务及运维 腾讯“创业•密码”开发者论坛 ChinaJoy引爆创业者关注 从F1赛车到智能手机,无线充电技术之崛起 助力梦想!MDCC免费为优秀App开发团队提供展位 为Symfony2和Redis正名,基于PHP的10亿请求/周网站打造 【聚焦API】教你如何选择最适合的NLP API服务商? 直接改应用!Flipboard开源iOS应用内调试工具FLEX 专访腾讯游戏运营总经理崔晓春:云时代游戏运营的变革与创新 嵌入式专家Bruce Douglass经验谈 门票销售过半 从2014微信开发者大会购票者特征说起 当来自金星的Devs碰上火星的Ops——共话应用扩展 移动平台市场占有率:Android首次赶超iOS 豌豆荚范怀宇 I/O大会总结:Android无处不在 关于自增长字段使用的问题,高手请进 这一贴,分就少点了,就这么多啦 有人能告诉我广东省C程序员与JAVA程序员的薪水比较吗?为什么会有这种差距呢 请问用javaApplet如何控制IE界面? 点对点的讨论 水平考试与资格考试及格分别是多少分? 如何再网页中实现打印功能,份也打印。 我发现了一个网站的BUG,我该怎样进去? 到处都是泡泡,俺看的想吐,晚上再来算了。 怪事, 屏幕变黑白 我的问题_6 MYSQL中like的问题 请教打印预览问题 请问,如果我想把,file edit tools window这个主菜单栏动态去掉,怎么做? 如何用程序代码实现在Memo文本编辑框中被选中的文字加下划线。 怎样分析tcp报文(我很急呀) *.idl文件如何使用? 各位大侠,怎么写一个php在线打分的程序阿? 我测试一下 感兴趣的去试试! IE外壳扩展的程序 Delphi 6.0的一个Bug??? 我怎么把字符串放进缓冲里?急急急!!! 恭喜 zhipop 喜得漂亮的可爱的千金 几个小问题想请教大家 如何将浏览器的地址栏里的IE图标换成自己的图标? r俺明天想去给我的宝马生生级,不算显示器,3000元左右,请各位大侠们赐教该什么配置 2000下写的程序,NT 4.0workstation上为什么不能跑? 启用新主页下载数据窗口编辑器 请教Qbasic中的几个问题..... 用BCB如何向Oracle8.0.5中更新BLOB 用ODBC编程时发现错误:nvarchar 类型无数据类型同其绑定,用CString 出错!如何解决? 救命,救命!!!!!!!!!!!! 【 这两天好像来了很多新人嘛!来报个到吧! 】 请教:如将一个 FormView 的 ScrollBar 去掉 在asp中怎么定义可变长的数组? 关于文本框的问题(你能回答吗?) X档案第三季有一集叫《网络情人》,讲的什么内容? 如何登陆interbase de local server? 确定星座是按农历,还是公历????? 请问哪里能买到苹果7300主板,大概多少钱? vc高手快来帮我 我可以通过style定义普通字体的大小,却不能定义表格中字体的大小 BDE + SQL AnyWhere6.0问题!求救!SOS! 最新消息:泡泡是个PLMM 如何实现关机前所有文挡的自动保存 兄弟要进行一项庞大的工程 . 输全国县以上地区的编码. 我用powerbulider设计了一个报表,如何能在vc程序中使用这个报表 如何用回车键代替tab键在sle之间移动焦点 讨论:关于翻译英文文章的版权问题????????? 【 本人收到N多从+888发来的短信息,内容是:此信息无法显示!Faint! 】 家庭电路中,电压一定220V,电炉子的电阻很大,根据P=U方/R,功率应该很小,但为什么电炉子的功率却很大?而且其他用电器的电阻越大,功率还越大? 请问:一千瓦等于多少马力 500克等于多少个100毫克 24v的交流电热圈功率是1000瓦,那么电流是多少?能电倒人吗? 空调多少匹是怎么换算出来的,空调匹数跟瓦数怎么换算,1千瓦等于多少马力? 2000毫升水有多少千克此问题对我很严重.还请各位尽量回答我. 一个电炉子功率2000瓦每天用5小时一个月按30天计算电费是多少 一马力等于多少瓦? 50毫升B摩尔每升的ALCL3溶液加入50毫升A摩尔每升氢氧化钠溶液当A小于等于3b时生成氢氧化铝的沉淀物质的量 电炉子工作时,是将电能转化成热能,电炉子工作时,是将电能转化成热能;电炉子工作时,是将电能转化成热;电炉子工作时,是将电能转化成内能!哪种说法正确!三者有什么不同? 功率和马力是怎么换算? 向20毫升氯化铝溶液中滴入2摩尔每升氢氧化钠溶液时,沉淀质量与所滴加氢氧化钠溶液体积(ml)铝离子完全沉淀时沉淀质量为0.78g,假设溶液中有氢氧化铝0.39克,则此时用去氢氧化钠溶液的体积 一种炉子,电能的!既可以做电煮锅,又可以取暖!不是普通的光波炉之类的,有一定的高度,面积差不多80*80cm 还可以用作打麻将时取暖!知道的朋友介绍一下!最好给个链接!了解功能 价钱...不是电 功率和马力怎么换算现在汽车说的是功率,和原来的马力怎么换算? 向20毫升氯化铝溶液中滴入2摩尔每升的氢氧化钠溶液时,得到氢氧化铝沉淀的质量与所滴加氢氧化钠溶液体积关系如图所示.(1)图中A点表示的意义是____________.B点表示的意义是____________.(2)上 600瓦电烤火炉每小时用几度电? 1千瓦等于多少马力 如何配置0.5摩尔每升的无水碳酸钠溶液500毫升 我用最大功率1000瓦的电插座,插上一个做饭的电炉,是耗电1000瓦的.用多久拔掉安全点? 136匹马力等于多少千瓦也就是新B200的功率,随便说一下,这车真的买来值吗?是不是比以前的奔驰要缩水一些? 实验室用NaCO3·10H2O 晶体配制500毫升0.1摩尔每毫升的碳酸钠溶液 应称取NaCO3·10H2O 多少克 减震弹簧是一圈一圈紧挨着,还是一圈一圈有空隙 汽油机1千瓦等于多少马力汽油机和柴油机一样吗 取500毫升碳酸钠溶液与300毫升浓度为一摩尔每升的盐酸反应,在不断搅拌下将碳酸钠溶液逐滴滴入盐酸中与将盐酸滴入碳酸钠溶液中,所产生气体的物质的量之比为3:2.则碳酸钠的浓度是多少? 一度电是不是就等于一千瓦 那 1匹马力等于多少千瓦 配制500毫升2摩尔每升的硫酸溶液需浓度为百分之九十八,其密度为1.84克每立方米的浓硫酸呵水各多少 一千瓦是不是等于一度电?总搞不清,说清原因 1马力等于多少千瓦 如何配制溶液500毫升的碳酸钠溶液 一千瓦一小时几度电 请问1千瓦等于多少马力 用98%浓硫酸配制500毫升1.0摩尔每升的硫酸溶液? 多少伏等于一千瓦?一千瓦等于多少电流?同上 1马力等于多少千瓦时 用98%的浓硫酸(密度为1.84克每毫升)配制1摩尔每升的稀硫酸100ml,需要硫酸多少? 一度电是一千瓦时还是3.6*1000000瓦时 1马力等于多少功率 需要0.5摩尔每升的硫酸500毫升若使用溶质的酸进行配置,问题是:1.该浓硫酸的物质的量浓度 2.需要浓硫酸的 一千瓦一个小时一度电如何计算出来的介绍一下这一块儿的..我不是很懂... 一升等于多少公斤谢谢了,大神帮忙啊 在20毫升0.1摩尔每升醋酸溶液中逐滴加入20毫升0.1摩尔每升的氨水溶液,溶液导电能力逐渐增强.为什么? 114磅是多少公斤?磅和公斤的换算公式是怎样的呀? 舍得酒广告的含义 将20毫升0.1摩尔每升的醋酸钠与10毫升0.1摩尔每升的盐酸混合溶液显酸性,溶液中个离子浓度的比较 血的单位CC跟毫升跟克是怎么换算的 舍得酒经典台词 下列溶液中含氯离子物质的量浓度最大的是( ) A.30毫升0.2摩尔每升KCI溶液 B.20毫升0.1摩尔每升氯化钙溶液,C.10毫升0.1摩尔每升氯化铝溶液 D.100毫升0.25摩尔每升氯化钠溶液 请问功率1000瓦的电器,它的电流是多少? 体积CC和毫升怎么换算? 舍得的含义?如何舍得,如何取舍 1安培等于多少瓦? cc和毫升怎么换算啊?cc和毫升有什么关系?它们之间应该怎么换算?2000cc等于多少毫升?急用!谢谢了!~ 怎样辨别舍得酒的真假想买一瓶给老爸,还怕买到假酒,请懂行的朋友帮帮忙!积分不多, 请问35瓦等于多少安培?1:35瓦等于多少安培?2:蓄电池上标有12v/7ah 请问后面的7ah是什么意思? CC与毫升是怎么换算的? 250毫升等于多少毫克 一安培等于多少瓦 毫升怎样换算成斤,公式是怎样的.我说的是酒 请问250毫克等于250毫升吗?
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn