阅读更多

4顶
4踩

Web前端

转载新闻 谈谈UI架构设计的演化

2015-02-12 16:44 by 副主编 mengyidan1988 评论(3) 有8436人浏览
【编者按】近日,阿里无线事业部前端工程师寒泉在一篇文章《谈谈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已经没法作为一种交流的标准词汇了。

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

原文来自:寒泉的微博文章
  • 大小: 12.6 KB
  • 大小: 26.9 KB
  • 大小: 26.6 KB
  • 大小: 28 KB
  • 大小: 14.5 KB
  • 大小: 38.1 KB
4
4
评论 共 3 条 请登录后发表评论
3 楼 文仁126520 2015-02-25 17:53
不知所云
2 楼 yuechen323 2015-02-17 20:50
啥也没说,作者自己又画图又写文章的,白忙活一场
1 楼 smiky 2015-02-15 08:57
默名其妙

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • Risk of rain 2 Linux 服务器搭建

    Risk of rain 2 Linux 服务器搭建 搭建环境 腾讯轻量应用服务器云2核4G 6M带宽 Ubuntu 20.04.4 LTS x86_64 搭建步骤 1.安装Wine-7.0 2.安装、启动ror2服务器 3.(重要)补全steam依赖 4.日志展示 5.运行时情况

  • Linux环境下Risk of rain 2(雨中冒险2)服务器搭建

    过了一会会后发现,这游戏的官方服务端没有Linux版本,只有一个Windows版本的,这就把哥们难住了。接下来就仔细地讲讲完整的搭建过程,顺便让那位摸鱼了一个寒假的哥们看看怎么安装环境。 我采用的是Cento.

  • 云服务器搭建ThinkPHP框架图文教程

    使用本教程进行操作前,请确保已经有了云服务器,对于服务器配置选择有疑问,请参阅服务器实例规格。 背景信息 本教程适用于正在学习PHP或者已基于ThinkPHP框架进行研发的开发人员。 操作步骤 使用云市场镜像快速...

  • Mac + raspberrypi NAT模式搭建公司备用服务器

    所以萌生了带家里的树莓派过来搭建个人项目测试服务器的想法,对接测试环境数据库,这样既缓解开发主机压力,并且能作为团队的备用测试环境 我的raspberry pi版本: raspberry pi 4B + 8G RAM + Ubuntu 20.04 mac主机...

  • Linux下搭建ISCSI存储并用WindowsServer做FTP共享

    本篇文章将会教你如何搭建简易的类似于前后端存储实验准备(以下实验都在VMware中进行)一、Linux主机上1、配置yum软件仓库2、安装 iSCSI服务端程序3、配置 iSCSI服务端共享资源4、创建 iSCSI target名称及配置共享...

  • 搭建ROR开发环境备忘

    一、搭建RUBY开发环境 1.这是RUBY的官网,可以在这里下载到最新版本:http://www.ruby-lang.org/ 2.下载到文件ruby-1.8.7-p72.tar.gz(说明:本人在linux系统) 3.开始安装我们的ruby 解压文件:$ tar -xvf ruby...

  • Gitlab搭建内网服务器一篇就够

    0 写在前面首先大概捋一下概念:Git是版本管理工具,GitServer是远程管理仓库,但是这个仓库没有界面只能命令行管理。多个仓库时又很麻烦,Gitlab是一个私有的仓库Web管理工具,基于RoR。GitHub则可以看成一个世界级...

  • ubuntu13.10安装mysql_ubuntu13.10搭建ror开发环境1--安装mysql

    三种安装方式:1. 从网上安装 sudo apt-get install mysql-server。装完已经自动配置好环境变量,可以直接...2. 安装离线包,以mysql-5.0.45-linux-i686-icc-glibc23.tar.gz为例。3. 二进制包安装:安装完成已经自动...

  • linux下lighttpd + fcgi的ROR环境搭建

    robbin对lighttpd和fcgi的环境搭建阐述的已经非常详细,建议大家去熟读下,他对lighttpd + fcgi进行了高度的评价,并且从javaeye的事实运营过程当中我们也看到了确实这2个服务器的搭配显得非常的默契,是现今ROR最好...

  • linux下nginx + mongrel的ROR的集群环境搭建

    ror的生产环境的搭建过程当中可以有多种web server和app server的选择和搭配,其中nginx + mongrel的组合是众多选择当中... 建议在搭建ROR的生产过程之前,能够对javaeye老大robbin的关于ROR服务器的相关文章进行...

  • Linux(CentOS)搭建redmine项目管理系统

    由于服务器(CentOS6.8)没有预装ruby、ROR(Ruby on rails)环境,本文内容是从0开始搭建的,中间也吃了不少软件兼容性等的苦头,参阅了不少文章,遂做下笔记,希望对有同样需要的同仁有些帮助。有关redmine的介绍...

  • apache+mongrel+rails+linux轻松架设服务器

    1.首先在服务器上搭建RAILS环境并装mongrel 和apachelinux下ROR的配置 (ubuntu) ...

  • linux系统搭建Ruby on Rails最佳开发环境

    Ruby on Rails,也称 RoR 或简称 Rails,是一个使用Ruby语言写的开源网络应用框架,它是严格按照MVC结构开发的。Rails的设计原则包括“Dont Repeat Yourself”)和“Convention Over Configuration”。近年来出现...

  • 搭建 CentOS 6 服务器 - 目录

    搭建 CentOS 6 服务器 - 目录 博客分类: Linux (1) 安装CentOS ISO(desktop/minimal)、Cloud(AWS/阿里云)、Virtualization(VMWare、VirtualBox)详细内容 (2) Linux常用命令 cd、ls、rm、...

  • redmine linux环境安装搭建

    linux环境搭建ROR环境变量 参考:[url]http://www.iteye.com/topic/43228[/url] redmine1.1.1的官方配置要求如下: [code="java"]ruby 1.8.7 rails 2.3.5 gem 1.3.5 rack 1.0.1[/code] [b]最初我没...

  • RoR部署方案深度剖析

    RoR的部署方案可谓五花八门,有Apache/Fastcgi方式的,有Nginx/Mongrel方式的,还有lighttpd/Fastcgi方 式,也有人使用HAProxy/Mongrel,各种部署方式都是众说纷纭,让人搞不清楚哪种方式更好一些。我的这篇文章就是...

  • harbor配置远程仓库

    用第一篇搭建后要注意,第二篇中用的是80,你要全部写端口。这个教你配置,login登录。上面教你按harbor。

  • Redmine搭建教程

    Mongrel是一种快速的针对Ruby的Http服务器,专门为部署发布ROR应用而产生的。 Mongrel相比Rails自带的纯Ruby服务器Webrick速度快很多并支持并发访问,有望成为Ruby的Tomcat. 改善webrick访问速度。 1. 替换其自带...

  • CentOS5.2 + NetBeans6.1搭建ROR的IDE环境

    今天准备搭建ROR的IDE环境了, 这个其实挺简单的,首先到http://java.sun.com/javase/downloads/index.jsp 下载最新的JDK,然后安装,我是装到/usr/local/jdk1.6.0_10/的,接下去会 用到这个路径,然后去...

  • pendulum-2.1.2-cp39-cp39-win32.whl.rar

    python whl离线安装包 pip安装失败可以尝试使用whl离线安装包安装 第一步 下载whl文件,注意需要与python版本配套 python版本号、32位64位、arm或amd64均有区别 第二步 使用pip install XXXXX.whl 命令安装,如果whl路径不在cmd窗口当前目录下,需要带上路径 WHL文件是以Wheel格式保存的Python安装包, Wheel是Python发行版的标准内置包格式。 在本质上是一个压缩包,WHL文件中包含了Python安装的py文件和元数据,以及经过编译的pyd文件, 这样就使得它可以在不具备编译环境的条件下,安装适合自己python版本的库文件。 如果要查看WHL文件的内容,可以把.whl后缀名改成.zip,使用解压软件(如WinRAR、WinZIP)解压打开即可查看。 为什么会用到whl文件来安装python库文件呢? 在python的使用过程中,我们免不了要经常通过pip来安装自己所需要的包, 大部分的包基本都能正常安装,但是总会遇到有那么一些包因为各种各样的问题导致安装不了的。 这时我们就可以通过尝试去Python安装包大全中(whl包下载)下载whl包来安装解决问题。

Global site tag (gtag.js) - Google Analytics