Live软件开发面面谈——MVC

Posted starrow

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Live软件开发面面谈——MVC相关的知识,希望对你有一定的参考价值。

第3章  MVC

假如问一群程序员,谁是最有价值厨师?他们大概会在短暂的茫然后给出五花八门的答案,男朋友、老婆、老妈或者某家快餐连锁店的幕后大厨。显然他们对这个概念还不太熟悉,但是如果把它翻译成英文Most Valuable Cook,有些人或许就明白了。假如还不知道,说出它的简称,他们就一定很熟悉——MVC。

MVC可谓是图形用户界面软件设计的标准模式。无论采用哪种编程语言,设计的是桌面端、Web还是移动端应用程序,采用的是流行的或冷门的开发框架,遵行MVC都几乎是必然的。然而另一方面,就像一千个人眼中有一千个哈姆雷特,当人们谈论MVC时,也像谈论爱情一样,所指千变万化。

视图没有直接从模型获得更新,而是由控制器修改视图,这违背了MVC的设计原则。控制器应该对视图的细节一无所知。事件响应程序可以直接写在视图内。控制器负责系统的业务逻辑。诸如此类都是我在各处看到的关于MVC的断言。在其他地方,又可以看到截然相反的论断。这些被我当成反面教材列出来的话语可不是初学者的臆想,它们都是来自Google相关关键字搜索的结果前列,有的是Oracle官方网站上对MVC的介绍文章,有的是俄亥俄州立大学计算机科学与工程系的主题讲义,有的是编程社区网站的热门和高票文章。代码样例是程序员学习的重要来源。不幸的是,同样来自Google搜索结果排名前列的MVC的样例代码在我初步看来,可以分为三个等级,不敢恭维、不忍卒读和惨不忍睹。很难相信这些代码的作者会以他们对MVC这样的理解和代码风格在实际项目开发中应用MVC模式。

平心而论,会有这样的现象,部分原因是MVC不像Singleton之类的设计模式那样具体,没有精确的代码对应形式,而且在广泛的应用中,根据环境要求和不同编程语言的特点也产生了不少变体,如MVP(Model-View-Presenter),从而令得不同情况下三个组件所负责的功能和实现方式有所出入。这样的弹性和变化进一步让MVC在传播过程中,像故事的流传一样衍变出形形色色的版本,又像娱乐节目上经常出现的接力猜谜,每一个人从上一个人的动作中猜出在模拟什么东西,再以自己的方式表演给下一个人看,到最后一个人猜出的东西往往和最初的风马牛不相及。要应对这样的困境,最好的方法是不光知其然,还要知其所以然。本章就将从简单程序的结构入手,逐步分析一个自然合理的架构随着程序的演变,如何发展成MVC。从分析MVC架构体现的设计理念辨清它的真相,理解在它的种种变体中哪些不变的部分是逻辑要求的必然结果,又有哪些部分可以适应需求、环境和实现技术做出灵活的选择。这之后再讨论桌面、移动和Web环境下MVC的具体实现。

3.1  输入、处理和输出

输入、处理和输出是早在计算机出现之前就可以从人类发明的很多机器抽象出来的模式。对蒸汽机来说,输入的是煤,处理是燃烧产生蒸汽,输出的是机械动力;电灯输入的是电流,处理是灯丝通电升高到足够的温度,输出的是光。而最典型的可能莫过于一台全能猪利用机,输入的是活猪,处理是在一个闪闪发光的密封金属舱中轰隆隆地进行,输出的是香肠、皮鞋、毛刷和骨头汤。所以从计算机的架构中也能看出这种模式,是毫不奇怪的。这种抽象的模式不仅适用于硬件,对我们关心的程序开发而言也是一种很自然的结构。本节就将探讨它在命令行程序中的表现形式。

3.1.1  冯诺依曼架构

1936年英国数学家图灵(Alan Turing)提出了一种想象中的机器,图灵机。这种机器的构造十分简单,只包括一条无限长的带子、一个读写头和一个状态存储器,然后机器根据读写头读取到的符号和当前状态以及有限条规则操作。图灵表明任何一项具体的计算,都可以由一台特定的图灵机完成。再进一步,将描述如何进行一项具体计算的规则也记录在带子上,由一台特殊的图灵机读取,那么它就可以完成那台特定的图灵机的计算。这样一台可以模拟所有图灵机,也就是可以进行任何计算的特殊的图灵机就被称为通用图灵机,它是现在所有计算机理念上的先驱。

1945年,出生于匈牙利的数学家、物理学家和科学全才约翰•冯•诺依曼(John von Neumann)在美国的宾夕法尼亚大学参与埃尼阿克研制工作时向美国军方提交了First Draft of a Report on the EDVAC(电子离散变量自动计算机报告初稿,EDVAC即Electronic Discrete Variable Automatic Computer)。这份报告虽然只有个不起眼的名称“初稿”,却和其他奠基性的文献一样,完整地建立了一台电子计算机的架构。冯•诺依曼首先描述了作为主题对象的“计算机”,它是一台能高速计算的电子设备,胜任求解物理和工程中常见的多变量偏微分方程,把要解决的问题的参数和描述求解方法和步骤的命令以某种方式输入后,它就能在没有任何人工辅助的条件下将结果计算出来并以某种方式输出。接着冯•诺依曼将计算机从逻辑上分成五个部分,分别完成特定的功能。这台机器被设计的主要用途是进行数学计算,所以自然有一个部分专职于此,即中央算术组件(Central Arithmetical Part,我们把它简称为运算器),它负责进行加减乘除等基本运算;第二部分叫做中央控制组件(Central Control Part,简称为控制器),负责执行指令,指挥运算器所做计算的次序,协调计算机的所有组件统一工作。第三部分称为存储器(Memory),用于保存计算过程中用到的各种信息,包括要解决的问题和计算产生的中间数据等。冯•诺依曼列举了计算机可能用于解决的各种数学问题,分别估计它们需要多大的存储空间。第四部分是输入设备,计算机的操作员通过它将待解决的问题和计算机执行的命令输入计算机,冯•诺依曼提到了当时可用于此的几种技术:在打孔卡或电传打字机纸带上打孔,在钢带或钢线上用磁记录,在电影胶卷上用摄影技术记录,通过插接板的连线配置……不过在这个人类发明的长长清单里键盘还没有出现。第五部分与第四部分相对,是输出设备,用于将计算结果传导到某种人可以直接或间接读取的载体上,也是利用上面列举的技术。

这份报告不仅指导建成了一台电子计算机,而且其中的很多讨论和分析对以后世世代代的计算机都有效,原因就是它一方面体现了最一般的自动计算机模型——图灵机的思想,另一方面又将通用图灵机的模型用更贴近实际制造和操作的方式设计出来,并且以当时的电子技术为基础,对计算机的各个部分做了具体的分析。报告将计算机从逻辑上分解成运算器、控制器、存储器和输入输出设备五大部分,也被后人称为冯诺依曼架构。计算机已经经历了从“埃尼阿克”的庞然大物到如今智能手机的人手一部的沧桑巨变,然而五大部分的分类仍然有效。

将冯诺依曼架构和通用图灵机模型作比较,计算器、控制器和存储器三者的组合已经实现了通用图灵机的功能,输入和输出设备则是人类与机器交互的手段。我们再从机器转向程序的视角,每个具体的软件都具备一个或一组特定的功能,计算机读取和执行该软件的代码,就变成了一台特定用途的图灵机。软件的用户以某种渠道输入数据,软件进行处理,完成后再以用户能理解的方式输出。这样类比于冯诺依曼架构,一个软件就可以被划分为输入、处理和输出三部分。这个划分看上去平凡无奇,但接下来的讨论将让我们看到它是怎样逐渐演变成MVC模式的。另外为了和MVC对应,我们给输入处理输出结构也起了一个很酷的简称IPO(根据三部分的英文Inputter、Processor和Outputter)。

3.1.2  矩阵运算器和IPO
3.1.3  矩阵运算器和IPO的升级版
3.2  程序与用户的交互
3.2.1  三类应用程序
3.2.2  持续交互带来的变化
3.2.3  图形用户界面带来的变化
3.3  设计理念
3.3.1  关注点分离
3.3.2  模型
3.3.3  模型和视图的分离
3.3.4  控制器
3.3.5  模型视图
3.3.6  事件发布者与收听者之间的依赖
3.3.7  合作方式
3.4  桌面应用程序与移动App
3.4.1  控制器和视图在代码单元上独立
3.4.2  控制器、视图和模型之间的相互引用
3.4.3  控制器和视图合一
3.4.4  移动App
3.5  Web应用程序
3.5.1  Web应用程序简史
3.5.2  服务器端的MVC
3.5.3  前端控制器与控制器
3.5.4  视图
3.5.5  模型
3.5.6  依赖注入
3.5.7  浏览器端的MVC
3.6  类型转换、校验和数据绑定
3.7  MVC的意义

更多内容,请参看拙著:

《Live软件开发面面谈》(京东)

《Live软件开发面面谈》(当当)

《Live软件开发面面谈》(天猫)

以上是关于Live软件开发面面谈——MVC的主要内容,如果未能解决你的问题,请参考以下文章

Live软件开发面面谈——接口

Live软件开发面面谈——事件

VSTO开发中级教程初稿目录

前端MV*

0321《软件工程》前三章总结(初稿)

教学日历(初稿)