当前位置: 首页 > 编程日记 > 正文

谈谈UI架构设计的演化

谈谈UI架构设计的演化

经典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之间很奇葩的依赖关系:

image

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

image

值得一提的是,其实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获得的了:

image

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

image

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

image

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

标记语言和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的概念的区别。这里简单画了一下:

image

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

结语

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

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

写此文,希望大家能了解些历史上的发展历程,莫被不严谨的文章误导。其实本文的相当多观点也是经过演绎的,所以我附上所有原始文献链接,希望大家看了以后能有自己的判断:)也欢迎大家据此指出我理解的错误之处。

参考资料

  • MVC论文
  • MVC论文翻译
  • MVP论文
  • MVVM博文
  • MVVM博文翻译

相关文章:

JWT(JSON Web Token)简介及实现

JWT(JSON Web Token):是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间作为Json对象安全地传输信息。由于此信息是经过数字签名的,因此可以被验证和信任。可以使用HMAC SHA256或RSA等对JWT进行签名。 JW…

iOS UIImageView 加载含有汉字的url处理方法

NSString *url [model.pic stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; [self.headImgView sd_setImageWithURL:[NSURL URLWithString:url]];

《评人工智能如何走向新阶段》后记

由AI科技大本营下载自视觉中国自《评人工智能如何走向新阶段》一文发表(在内部)后,引来了中外专家、草根们的广泛议论,有深有浅,其中似有一些思考价值,故录入本文后记: 中外专家、草根们23条议…

用XCA(X Certificate and key management)可视化程序管理SSL 证书(3)--创建自己定义的凭证管理中心(Certificate Authority)...

在第“用XCA(X Certificate and key management)可视化程序管理SSL 证书(2)---创建证书请求”章节中,我们介绍了怎样用XCA创建SSL证书请求(Certificate Request),在一章节中&#xf…

C和C++安全编码笔记:并发

并发是一种系统属性,它是指系统中几个计算同时执行,并可能彼此交互。一个并发程序通常使用顺序线程和(或)进程的一些组合来执行计算,其中每个线程和进程执行可以在逻辑上并行执行的计算。这些进程和(或)线程可以在单处理器系统上使用分时抢占…

《评人工智能如何走向新阶段》后记(再续1)

由AI科技大本营下载自视觉中国中外专家、草根对《评人工智能如何走向新阶段》一文进行广泛议论,已在《后记》中发表原创(未加修改)的23条议论,现再续发24-30条如下: 24.最近半年来,人工智能的发展重心逐渐…

iOS UITextView 随键盘弹出界面上移

- (void)textViewDidBeginEditing:(UITextView *)textView { CGRect frame textView.frame; int offSet frame.origin.y 70 - (self.view.frame.size.height - 216.0); //iphone键盘高度为216.iped键盘高度为352 [UIView beginAnimations:"ResizeForKeyboard" co…

H3C 交换机命名规则

例:H3C-S5500-28C-EIH3C:为固定值,就是“H3C”这个品牌S的位置:代表产品系列『S 代表交换机SR 代表业务路由器』第一个5的位置:代表产品子系列号『3系为千兆上行,百兆下行的合适交换机 例:S3600 S31005系为全千兆的盒式交换机 …

iOS 时间选择器封装(含三种模式)

#import <UIKit/UIKit.h> typedef enum : NSUInteger { DatePickerViewDateTimeMode,//年月日,时分 DatePickerViewDateMode,//年月日 DatePickerViewTimeMode//时分 } DatePickerViewMode; protocol DateTimePickerViewDelegate <NSObject> optional /** * 确定按…

C和C++安全编码笔记:总结

《C和C安全编码》(原书第2版)这本书是2013年出版的。 这里是基于之前所有笔记的简单总结&#xff0c;笔记列表如下&#xff1a; 字符串&#xff1a;https://blog.csdn.net/fengbingchun/article/details/105325508 指针诡计&#xff1a;https://blog.csdn.net/fengbingchun/…

《评人工智能如何走向新阶段》后记(再续2)

由AI科技大本营下载自视觉中国从朋友那里获知&#xff0c;有一块供大家自由议论人工智能的园地&#xff08;内部的&#xff09;&#xff0c;我通过有关关系进入后&#xff0c;一览之余&#xff0c;果然生动活泼&#xff0c;没有学究气&#xff0c;从已发表的30条议论来看。有原…

Dokku和Docker的完美配合

看到一篇不错的文章&#xff0c;收藏一下&#xff1a; 【编者的话】本文作者介绍了如何在单机上将Dokku和Docker结合。Dokku是一个小型的PaaS平台&#xff0c;只需使用Git将代码push到对应的仓库上就能自动触发部署&#xff0c;构建过程非常简单。但是Dokku对于用户来说&#x…

iOS封装分页效果

#import <UIKit/UIKit.h> interface WPageTitleView : UIView property (nonatomic,assign) NSInteger selectedIndex; //添加参数数组 property (nonatomic,strong) NSArray *titles; property (nonatomic,copy) void (^buttonSelected)(NSInteger index); end #impo…

Windows/Linux TCP Socket网络编程简介及测试代码

典型的网络应用是由一对程序(即客户程序和服务器程序)组成的&#xff0c;它们位于两个不同的端系统中。当运行这两个程序时&#xff0c;创建了一个客户进程和一个服务器进程&#xff0c;同时它们通过从套接字(socket)读出和写入数据在彼此之间进行通信。开发者创建一个网络应用…

《评人工智能如何走向新阶段》后记(再续3)

由AI科技大本营下载自视觉中国35.阿里巴巴旗下芯片公司平头哥在乌镇互联网大会上宣布开源低功耗微控制芯片&#xff08;MCU&#xff09;设计平台&#xff0c;这一平台面向 AIoT 时代的定制化芯片设计需求&#xff0c;目标群体包括芯片设计公司、IP 供应商、高校及科研院所等&am…

ffmpeg 基本用法大全

FFmpegFFmpeg 基本用法本课要解决的问题1.FFmpeg的转码流程是什么&#xff1f;2.常见的视频格式包含哪些内容吗&#xff1f;3.如何把这些内容从视频文件中抽取出来&#xff1f;4.如何从一种格式转换为另一种格式&#xff1f;5.如何放大和缩小视频&#xff1f;6.如何旋转&#x…

快过年了,为过完年跳槽的人准备一份面试题

设计模式是什么&#xff1f; 你知道哪些设计模式&#xff0c;并简要叙述&#xff1f; 设计模式是一种编码经验&#xff0c;就是用比较成熟的逻辑去处理某一种类型的事情。 1). MVC模式&#xff1a;Model View Control&#xff0c;把模型 视图 控制器 层进行解耦合编写。 2). MV…

Ubuntu上Vim安装NERDTree插件操作步骤

NERDTree是Vim的文件系统浏览器&#xff0c;使用此插件&#xff0c;用户可以直观地浏览复杂的目录层次结构&#xff0c;快速打开文件以进行读取或编辑&#xff0c;以及执行基本的文件系统操作。NERDTree源码在https://github.com/preservim/nerdtree。 这里通过Vundle安装NERD…

《评人工智能如何走向新阶段》后记(再续4)

由AI科技大本营下载自视觉中国41. 在人工智能感知阶段&#xff0c;依靠数据驱动的深度学习算法。目前5种最流行的深度学习架构: ① 递归神经网络&#xff08;RNN&#xff09;② 长短期记忆 &#xff08;LSTM&#xff09;/门控递归单元&#xff08;GRU&#xff09;③卷积神经网络…

电视游戏会是未来客厅娱乐的主角吗?

在时下流行的多屏生态概念中&#xff0c;电视虽为最大屏幕&#xff0c;但与智能手机、平板等小屏相比&#xff0c;属于相对较弱的一环。无移动性、自身交互性不足&#xff0c;在一定程度上影响着它在移动时代的发展。而作为最能体现其“吸睛能力”的——大屏娱乐功能&#xff0…

王爽著的《汇编语言》第3版笔记

王爽著的《汇编语言》(第3版)于2013年出版&#xff0c;虽然是2013年出版的&#xff0c;但书中部分内容感觉已过时&#xff1a; (1). 基于intel 8086 CPU介绍&#xff0c;intel 8086是英特尔公司上个世纪生产的芯片&#xff0c;是16位的&#xff0c;早已停产&#xff1b; (2).…

iOS 倒计时方法

//启动计时器 double delayInSeconds 10.0; dispatch_time_t popTime dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ //执行事件 NSLog("计时器结束了"); UIAlertController …

《评人工智能如何走向新阶段》后记(再续5)

由AI科技大本营下载自视觉中国51.今年发表的由俄罗斯“脑机接口”公司&#xff08;Neurobotics&#xff09;和莫斯科物理技术学院&#xff08;MIPT&#xff09;研究的一种全新“脑机接口”算法。利用“脑机接口”将人脑&#xff08;EEG&#xff09;神经元与脑外深度学习网络连接…

不说12306你会Die啊?当然不会,但会憋死

别嫌这标题话粗啊&#xff0c;只是突然想起了某小品中的一句台词儿而已。又是一年春运时&#xff0c;几十亿人口开始了兴奋着、痛苦着的大迁徙。12306开通有几年了吧&#xff0c;我今年才第一次用。因为父母要回老家&#xff0c;不想排队那么辛苦&#xff0c;所以才尝试一把网络…

汇编程序设计与计算机体系结构软件工程师教程笔记:处理器、寄存器简介

《汇编程序设计与计算机体系结构: 软件工程师教程》这本书是由Brain R.Hall和Kevin J.Slonka著&#xff0c;由爱飞翔译。中文版是2019年出版的。个人感觉这本书真不错&#xff0c;书中介绍了三种汇编器GAS、NASM、MASM异同&#xff0c;全部示例代码都放在了GitHub上&#xff0c…

iOS 发布APP关于IDFA的相关内容

您的 App 正在使用广告标识符 (IDFA)。您必须先提供关于 IDFA 的使用信息或将其从 App 中移除&#xff0c;然后再上传您的二进制文件。 如果出现下边这两张图&#xff0c;你就会感到蛋蛋的忧伤 还有这个 怎么解决&#xff1f; 1&#xff0c;查看你所集成的SDK&#xff0c;看看…

《评人工智能如何走向新阶段》后记(再续6)

由AI科技大本营下载自视觉中国61. 在2019深度学习开发者峰会上&#xff0c;百度发布基于飞桨的图学习框架&#xff08;PaddleGraphLearning&#xff0c;PGL&#xff09;。近年来深度神经网络推动了人工智能的发展&#xff0c;但在实际场景中有大量数据是在非欧式空间的&#xf…

Android APP测试的日志文件抓取

1 log文件分类简介 实时打印的主要有&#xff1a;logcat main&#xff0c;logcat radio&#xff0c;logcat events&#xff0c;tcpdump&#xff0c;还有高通平台的还会有QXDM日志 状态信息的有&#xff1a;adb shell cat /proc/kmsg &#xff0c;adb shell dmesg&#xff0c…

汇编程序设计与计算机体系结构软件工程师教程笔记:指令

《汇编程序设计与计算机体系结构: 软件工程师教程》这本书是由Brain R.Hall和Kevin J.Slonka著&#xff0c;由爱飞翔译。中文版是2019年出版的。个人感觉这本书真不错&#xff0c;书中介绍了三种汇编器GAS、NASM、MASM异同&#xff0c;全部示例代码都放在了GitHub上&#xff0c…

IOS视频编辑功能详解上篇-添加水印

前言 用代码在简单视频编辑中&#xff0c;主要就是加美颜、水印&#xff08;贴图&#xff09;、视频截取、视频拼接、音视频的处理&#xff0c;在美颜中&#xff0c;使用GPUImage即可实现多种滤镜、磨皮美颜的功能&#xff0c;并且可以脸部识别实时美颜等功能&#xff0c;这个…