为什么MVC不是一种设计模式

2023-11-13

---比较Backbone和Ext4.x在MVC实现上的差异

 

大漠穷秋

 

前言

 

圣人云:不想做妈咪的小姐不是好码农。

 

每一个码农的心中都有一个终极理想,那就是有一天不用再Coding。

 

在成为妈咪的道路上,“设计模式”被认为是一项必备的技能。

 

因此,经常有湿主会问小僧这样一个问题:为什么MVC不是一种设计模式呢?

 

对于这样naive的问题,小僧向来是嗤之以鼻的,你们啊!图样图森破!

 

机缘巧合,前段时间在焦点技术大会上听到一位大牛关于Backbone的介绍,于是小僧最近一段时间研究了一下Backbone相关的内容。

 

在《Developing Backbone Application》(戳这里查看此书电子版)这本书上,恰好有几段关于MVC相关的内容,看完这段内容之后,小僧突然有醍醐灌顶之感。原来为什么MVC不是一种设计模式这个问题还真的是个问题,看起来是小僧自己执念太重了!

 

罪过罪过。

 

弥陀佛~~!

 

(淘宝的一位牛人白汀 @白汀UX 翻译了《Developing Backbone Application》这本书,完整的在线电子版请戳这里,小僧友情建议一下这位大牛,请注意翻译质量,错别字和语句不通顺的问题太多了点!)

 

为了让各位道友也能领悟到设计模式里面的一些奥妙,小僧特作此文。

 

稍安勿躁,让小僧给各位湿主解说一番。

 

(这里就不对着原文翻译了,为了方便各位道友理解,小僧总结一下其中的精髓,E文好的请点浏览器右上角。)

 

MVC的起源

 

1979年,Trygve Reenskaug 这位牛人在Smalltalk-80系统上首次提出了MVC的概念,最初的时候叫做Model-View-Controller-Editor。

 

(我擦,1979年小僧还在佛祖那儿念经呢吧?)

 

1994年,Gof(Gang of Four)在《Design Patterns: Elements of Reusable Object-Oriented Software》一书中对MVC模式做了深入的解析。

 

Trygve Reenskaug最初提出MVC的目的是为了把数据(Model)视图(View)分离开来,然后用控制器(Controller)作胶水来粘合M和V之间的关系。

 

很显然,这样做的目的是为了实现注意点分离这样一个更高层次的设计理念,也就是让专业的对象做专业的事情,View就只负责视图相关的东西,Model就只负责描述数据模型,Controller负责总控,各自协作,别总掺和到一起乱成一锅粥!

 

最古典的MVC实现

 

请注意上一小节中的两个年份,1979年,计算机还不是屌丝能玩儿得起的东西!那时候比尔盖茨还是个小学生,并且他还没有辍学创办MicroSoft,那时候人们不知道什么是Windows,当然,也没有什么GUI的概念。

 

各位道友可以想想一下,黑黑的命令行,一串一串的文本字符...

 

嗯嗯,就是那个样子的!

 

显然,在这样的历史背景之下,原始的MVC模式显然不是如今所理解的那种样子。

 

在Smalltalk-80上的那个古典实现上,View和Controller都是要监听Model的,也就是说,只要数据发生变化,视图和控制器都会收到通知的!

 

也就是这个样子的:

 



 

 

C和M,V和M之间都是通过Observer pattern (观察者模式)来实现的。

 

对于这种古典的实现细节,请参见Martin Fowler的这篇文章

 

为什么GOF的23种设计模式里面没有MVC?

 

好了,到这里应该来解释为什么MVC不是一种设计模式这个问题了。

 

对于这个问题,直接引用@白汀UX 的译文如下:

 

GoF (Gang of Four,四人组, 《Design Patterns: Elements of Reusable Object-Oriented Software》/《设计模式》一书的作者:Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides)并没有把MVC提及为一种设计模式,而是把它当做“一组用于构建用户界面的类集合”。在他们看来,它其实是其它三个经典的设计模式的演变:观察者模式(Observer)(Pub/Sub), 策略模式(Strategy)和组合模式(Composite)。根据MVC在框架中的实现不同可能还会用到工厂模式(Factory)和装饰器(Decorator)模式。我在另一本免费的书“JavaScript Design Patterns For Beginners”中讲述了这些模式,如果你有兴趣可以阅读更多信息。

正如我们所讨论的,models表示应用的数据,而views处理屏幕上展现给用户的内容。为此,MVC在核心通讯上基于推送/订阅模型(惊讶的是 在很多关于MVC的文章中并没有提及到)。当一个model变化时它对应用其它模块发出更新通知(“publishes”),订阅者 (subscriber)——通常是一个Controller,然后更新对应的view。观察者——这种自然的观察关系促进了多个view关联到同一个 model。

对于感兴趣的开发人员想更多的了解解耦性的MVC(根据不同的实现),这种模式的目标之一就是在一个主题和它的观察者之间建立一对多的关系。当这个 主题改变的时候,它的观察者也会得到更新。Views和controllers的关系稍微有点不同。Controllers帮助views对不同用户的输 入做不同的响应,是一个非常好的策略模式列子。

 

嗯嗯,知道为什么MVC没有被GOF当作【一种】模式来对待了吧?

 

因为它实际上是三种模式的合体

 

(如果以后有人问你这个问题,你可以直接引述上面这段话,绝对高端大气上档次!一下就能把TA给震住!)

 

前端MVC与经典MVC的差异

 

正如前文所述,在当初提出MVC这种设计理念的历史条件之下,基本上还没有图形界面,当然像JavaScript这种东西也是不存在的!

 

但是,如今不同了!在如今前端框架(尤其是各种JavaScript框架)大爆炸的背景下,几乎所有的框架都会号称自己具有MVC的特性。

 

但是,有一点请注意,如今的MVC实现与古典的MVC实现方式已经大不相同了。

 

下面拿Backbone和Ext来举两个例子。

 

Backbone中的MVC实现方式

 

对于最新版本的Backbone来说,它不再区分出独立的Controller,它的控制器代码与View是写在一起的,仅仅明确区分出了Model的概念,举个栗子:

 




 
 

 

呃,请不要在意那些细节,看红框的部分即可。

 

第一处,显然Employee是一个Model;

 

第二处和第三处,显然那EmployeeView是一个View;

 

第四处,setText这个方法显然是充当Controller的角色。

 

很显然,在Backbone的这种实现之下,View和Controller合体了,并没有抽象出独立的Controller这种东西。

 

显然,这是古典MVC的一个变种,也就是原书作者所谓的MV*。

 

各位道友请仔细想想,Backbone的这种做法有没有道理?

 

Ext4.x中的MVC实现

 

再来看Ext4.x中的MVC实现。 




 
 

 

从以上示例项目截图(controller/model/view等目录)可以看出来(此图来自Ext官方的说明文档),Ext4.x采用了古典的MVC设计方案,它明确地抽象出了Controller这个类

 

为什么小僧坚持认为Ext4里面的MVC是一种过度设计?

 

熟悉Ext历代版本的道友会知道,在Ext4.x之前,并没有做出前面这样的区分。

 

【以下纯属个人看法,仅供参考】

 

与Backbone相比,Ext4.x的这个设计纯属鸡肋,实际上,对于带有GUI界面的代码来说,Controller是无法独立于View而存在的。

 

因为,在Controller里面一定需要到处访问View中的内容,Controller是无法独善其身的!

 

Ext4.x的这个实现为了MVC而MVC的一个绝佳例子。

 

在Ext4.x中,类似为了模式而模式的例子不胜枚举,据小僧不怀好意的推测,这一定是Jack离开之后这帮人乱搞的结果。

 

这也是为什么Ext4.x的运行效率如此之差的原因,之一。

 

小僧都替你们捉急有木有?!!!

 

对于4.x的效率问题,网上的吐槽不计其数,各位道友可自行咨询度娘。

 

为什么小僧认为MVP/MV*才是最佳设计理念

 

这里请区分好概念,设计理念具体实现方式不是一回事。

 

在关于Backbone的这本书中,作者还提出了MV*和MVP (Model-View-Presenter) 的说法,不得不说,这是非常具有洞察力的见解。

 

其中的Presenter可以用来与服务端交互,获得Model数据,以及把Model提交到服务端等等。

 

在当前MVC很多的实现里面,与服务端的交互是写在Model里面的(Backbone和Ext都是这样)。

 




 
 

 

小僧认为,这种实现方式有待商榷,如果在Model里面含有后台交互的代码,在不同的场景下显然无法达到复用Model的目的。

 

比如,在场景一下面你希望数据模型访问 myApp/delUser.action,而在场景二下面你希望它访问 myApp/daddUser.action,这种情况你就麻烦了不是?

 

而且,与后台的交互过程应该抽象成独立的数据传输层,在这一点上Ext的实现略好。

 

因此,MV*、MVVM、MVP都可以看作MVC的现代衍生版,M和V一定要明确区分,至于要不要抽象出其它类,其它类是应该和M合体还是应该和V合体,各位道友看着办即可!

 

结语

 

当初提出MVC,是为了实现关注点分离这样一种设计理念,MVC只是实现这一理念的一种方式而已。因此,不必拘泥于一定要抽象出Model/View/Controller这样的类结构。

 

学习模式!运用模式!超越模式!

 

心中无码,一切都无码!

 

弥陀佛~~!

 

(请理性吐槽,否则回头小僧到佛祖那儿说你坏话,哼!)


http://damoqiongqiu.iteye.com/blog/1949256


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么MVC不是一种设计模式 的相关文章

  • 3Dmax 头发制作

    要在头顶创建头发 请使用样条线框架 此方法有助同时设计大量头发 尤其是长发 用于长出满头头发的样条线框架 样条线框架方法与络腮胡和唇胡所采用的多边形方法稍有不同 将从样条线 而不是从头部曲面 长出头发 没有任何毛发导向 样条线自身即为导向
  • 一些常见面试OO design题目总结

    最近很多公司面试喜欢问一些OO design的题目 我总结了一些比较高频的题目 需求不一定准确 设计的也不一定好 欢迎提出建议 1 电梯设计 2 停车厂设计 3 通用卡牌游戏blackjack设计 4 1 电梯设计 需求 以面向对象的方式设
  • Visio 画流程图 入门

    1 下载 Visio 2013 下载还是比较简单的 在此就不载详细讲解 贴一个链接给大家点击这里 2 新建文件 打开Visio会有如下界面 新建文件的方法有两种 首先来介绍一下第一种 类别选择 gt 模板选择 第二种 就是我们熟悉的 文件
  • 例解基于UML的面向对象分析与设计

    http www cnblogs com leoo2sk archive 2008 11 08 1329468 html 摘要 本文以实例的方式 展示了如何使用UML进行面向对象的分析与设计 本文将假设读者对UML 面向对象等领域的基本内容
  • 多媒体讲解器基本型设计

    多媒体讲解器功能按照播放器功能和灯光控制功能分类 播放功能分类 简易型 具备按键操作功能 TF卡升级 在线播放 U盘升级 在线播放 具备人体接近检测功能 红外 雷达 自动播放讲解功能 自动停止讲解功能 自动播放音乐 自动切换到讲解功能 切换
  • win系统电脑如何打开sketch?

    2 个方法快速使用 Windows 系统打开 Sketch 文件 使用 Adobe XD 打开 Sketch 文件或者使用浏览器中就能做设计的即时设计直接打开 Sketch 文件 众所周知 Sketch 只能在 Mac 电脑上使用 因此只有
  • log4cplus源码分析

    1 引题 虽然从本科起就学的C 然后在工作的2年时间中也不断的在用C 写代码 虽然基本的语法和一些常用的库函数已经滚瓜烂熟 可是总觉得自己写的代码还不是很专业 特别是看到那些老外们写得代码 从设计 到编码风格 再到各种编程技法的使用有很多都
  • 设计算法来统计一个输入字符串中所包含的整数个数,并输出这些数

    设计算法来统计一个输入字符串中所包含的整数个数 并输出这些数 假设输入的字符既有数字又有非数字的字符 例如 ak123x456 17960 302gef4563 其中连续数字作为一个整体看成整数 例如123 456等 include
  • 免费的插画素材网站有哪些?

    面对紧急设计项目 设计师会选择使用外力来完成项目 免费插图网站可以帮助我们在这个时候解决问题 但大多数插图网站都是收费的 需要版权或特别丑陋的 基本上很少有免费的没有版权的好插图 但今天我想推荐一个免费的插图网站 即时设计资源社区 即时设计
  • 基于接口设计原则-java

    7种设计坏味道 1 僵化性 很难对系统进行改动 因为每个改动都会迫使许多对系统其他部分的其它改动 2 脆弱性 对系统的改动会导致系统中和改动的地方在概念上无关的许多地方出现问题 3 牢固性 很难解开系统的纠结 使之成为一些可在其他系统中重用
  • 优先使用对象组合,而不是类继承

    http www cnblogs com nexiyi archive 2013 06 16 3138568 html 极限编程 Extreme programming 的指导原则之一是 只要能用 就做最简单的 一个似乎需要继承的设计常常能
  • sketch基础教程大全,对象、图层、画板常见技巧

    sketch对象 图层 画板的使用技巧 1 通过快捷键调整图形的形状 选择图形 按住Command按键 然后通过上 下 左 右方向键按1像素调整图形形状 同时按住按钮 CommandShift方向键 可调整方向键 2 复制元素 选择一个元素
  • App6种常见的数据加载设计

    设计师在进行APP设计的设计时 往往会更加专注于界面长什么样 界面和界面之间怎么跳转 给予用户什么样的操作反馈 却偏偏特别容易忽略掉一个比较重要的环节 就是APP数据加载中的设计 所以会导致我们看到的APP 往往有着华丽的启动界面 然后就是
  • axure到底好不好学,有哪些技巧

    Axure学习难吗 这个问题一直引起很多朋友的讨论 有的觉得难 有的觉得不难 当然 人不一样 每个人的学习方式也不一样 对学习难度的理解自然也不一样 这个问题自然没有定论 在学习的时候 有很多方法可以帮助我们 有不同的意见 我们需要尽可能多
  • 原型设计都有哪些好用的软件?

    原型图的设计软件只多不少 许多新人设计师都不知道怎么样在这些琳琅满目的选择中找到适合自己的 而且也不清楚主流软件究竟是哪些 接下来 本文将主要为大家介绍这方面知识 其实原型图设计有许多软件工具可选择 具体选择哪一款软件还是要取决于原型所需的
  • StarCraft开发:用肮脏的技巧解决难题

    http www csdn net article 2013 02 28 2814299 the starcraft path finding hack 摘要 在之前的文章中 Warcraft之父讲述了自己是如何以及为何重启StarCraf
  • Java语言基础

    01 01 计算机基础知识 计算机概述 了解 A 什么是计算机 计算机在生活中的应用举例 计算机 Computer 全称 电子计算机 俗称电脑 是一种能够按照程序运行 自动 高速处理海量数据的现代化智能电子设备 由硬件和软件所组成 没有安装
  • 老嫂子的保姆级科普 选择视频剪辑软件就从阅读本文开始

    选错一款视频剪辑软件 是种什么样的体验 就好像新婚当晚 发现老婆是人妖一样 浪费了感情 又错付了青春 新手在学习视频剪辑的初期 需要花费大量精力去熟悉剪辑软件的基础功能 而软件挑选本身没有对错可言 适合自己的才是最好的 因此 本文仅从事实与
  • Photoshop、Illustrator、Sketch哪个更好

    以前在交流组经常能看到大家争论哪个设计软件好 到底是你的吗 Illustrator好还是我的CorelDRAW或者他的Photoshop强大 但是跟着UI流行的设计 Sketch软件也加入了争论 让我们和你分享一下这篇文章 让我们来看看平面
  • 非常优秀的网站设计案例,设计师必备

    厚积才能薄发 一个优秀的设计师的天性一定是想要获得更多网站设计灵感 擅于为新项目寻找创意切入点 搜索设计参考资源 最新的设计趋势 今天为大家带来了一组免费可商用的网站设计案例 通过这些网站设计案例 你可以获得 寻找不同风格的网站灵感 配色

随机推荐

  • linux权限---【600,644,700,755,711,666,777】

    chmod命令详解 使用权限 所有使用者 使用方式 chmod cfvR help version mode file 说明 Linux Unix 的档案存取权限分为三级 档案拥有者 群组 其他 利用 chmod 可以藉以控制档案如何被他人
  • vue 项目在ie浏览器下报错CRIPT5022: SecurityError sockjs.js (1683,5)

    百度爸爸给的解决方法 找到 node modules sockjs client dist sockjs js 2 找到代码的 1605行 try self xhr send payload 注释掉 catch e self emit fi
  • Docker - 13. 容器卷常用操作

    目录 1 宿主和容器之间映射添加容器卷 2 查看容器卷是否挂载成功 3 容器卷 ro 和 rw 读写规则 4 卷的继承与共享 1 宿主和容器之间映射添加容器卷 公式 docker run it privileged true v 宿主机绝对
  • android studio调整代码和菜单栏字体大小

    1 File Settings Appearance Behavior Appearance 右边Override default fonts by not recommended 2 设置代码大小 File Settings Editor
  • 微信小程序组件知识点GET

    1 可滚动视图区域组件scroll view 在滚动 scroll view 时会阻止页面回弹 所以在 scroll view 中滚动 是无法触发下拉刷新事件 onPullDownRefresh 所以如果一定要使用下拉刷新 请使用页面的滚动
  • Clickhouse建表语法、视图语法、数据表DDL(数据定义语言)、数据DML(数据操作语言)...

    参考官网 https clickhouse tech docs zh sql reference statements create 更多详细文档可以参考官网 强烈推荐 1 Clickhouse创建数据库 CREATE DATABASE 该
  • 大年初四晚,Flutter Forward 中国社区直播活动与你不见不散!

    之前我们预告过 2023 年 1 月 25 日 年初四 Flutter 团队将在肯尼亚首都内罗毕举办 Flutter Forward 大会 并同时开启线上直播 本次活动将为展示最新的 Flutter 技术更新 包括一个主题演讲 以及多个技术
  • windows运行Elasticsearch内存占用过大

    运行Elasticsearch 内存占用差不多10G 编辑 elasticsearch 7 17 3 config jvm options文件 修改堆内存大小为4G Xms4g Xmx4g
  • Cisco Packet Tracer下载和安装、构建网络拓扑、配置网络设备、跟踪数据包、查看数据包

    Cisco Packet Tracer下载和安装 构建网络拓扑 配置网络设备 跟踪数据包 查看数据包 下载 一 注册Cisco账户 网址 https www cisco com c en us index html 二 注册Cisco学院的
  • CVPR 2023

    Title InternImage Exploring Large Scale Vision Foundation Models with Deformable Convolutions Paper https arxiv org abs
  • Matlab之colormap, FaceVertexCData

    首先说说colormap 它提供了一种着色方案 我认为它有3个作用 1 Matlab内置多种样式的color map 在任一个Figure中 打开菜单 Edit gt ColorMap 弹出 Colormap Editor 界面 在该界面上
  • linux 驱动——高级字符驱动程序操作

    内容 ioctl 的 ioctl 的系统概念 与用户空间同步的方法 进程休眠 非阻塞IO及与用户间的通信 原型函数 int ioctl struct inode inode struct file filp unsigned int cmd
  • week4作业题_A-DDL的恐惧

    A DDL的恐惧 题目描述 ZJM 有 n 个作业 每个作业都有自己的 DDL 如果 ZJM 没有在 DDL 前做完这个作业 那么老师会扣掉这个作业的全部平时分 所以 ZJM 想知道如何安排做作业的顺序 才能尽可能少扣一点分 请你帮帮他吧
  • 数据结构学习笔记(一)线性表

    文章目录 前言 一 线性表是什么 线性结构 线性表 二 线性表的顺序表示和实现 1 什么是线性表的顺序表示 2 代码实现 总结 参考资料 前言 文章目的在于记录学习数据结构这门课程中遇到的知识点以及难点 为解决或优化实际代码问题打好基础 一
  • 辨析BigDecimal的toString()方法和toPlainString()方法

    辨析BigDecimal的toString 方法和toPlainString 方法 toString toString方法会将BigDecimal的值以科学计数方式的字符串 但是转换成科学计数的方式也是有场景的 并不是所有的值都会转为科学计
  • Nginx 代理解决跨域问题分析

    当你遇到跨域问题 不要立刻就选择复制去尝试 请详细看完这篇文章再处理 我相信它能帮到你 分析前准备 前端网站地址 http localhost 8080 服务端网址 http localhost 59200 首先保证服务端是没有处理跨域的
  • Android注册登录页面

    Android注册登录页面 需求 分析 项目目录 java domain JsonBean java UserInfo java utils GetJsonDataUtil java Login java MainActivity java
  • 前端实现预览功能,播放rtsp视频流(node.js+ffmpeg+flv.js)

    实现思路 获取摄像头rtsp流 通过node js ffmpeg转码 通过哔哩哔哩flv js播放 1 获取摄像机RTSP流 之前文章有说明不多阐述 2 配置流媒体服务器 1 下载安装node js 运行node js 网上教程很多自行下载
  • XGBoost-工程实现与优缺点(中)

    工程实现 块结构设计 我们知道 决策树的学习最耗时的一个步骤就是在每次寻找最佳分裂点是都需要对特征的值进行排序 而 XGBoost 在训练之前对根据特征对数据进行了排序 然后保存到块结构中 并在每个块结构中都采用了稀疏矩阵存储格式 Comp
  • 为什么MVC不是一种设计模式

    比较Backbone和Ext4 x在MVC实现上的差异 大漠穷秋 前言 圣人云 不想做妈咪的小姐不是好码农 每一个码农的心中都有一个终极理想 那就是有一天不用再Coding 在成为妈咪的道路上 设计模式 被认为是一项必备的技能 因此 经常有