WEB项目中MVC与MVVM的思考

  • MVC 三者中,Model 是核心。Model,也就是模型,是对现实的反应和简化。你对问题的本质的描述就是Model。解决问题就是给问题建立Model。比如我们在现实中收发邮件的过程是什么样的?

    写好邮件,加上收信人地址,丢到邮筒。过几天去看看邮箱里有没有回信。地址不存在信会被退回来。

  • 你看这是不是和电子邮件的使用过程一样?无非就是把现实中的过程简化之后,搬到计算机上了而已。模型描述本质问题,忽略细节。当我们关注业务问题时,只有描述 “用户所关心的问题” 的代码才是 Model。
    当你的关注转移到其他问题时,Model 也会相应发生变化。失去了解决特定问题这一语境,单谈 Model 没有意义。

    对于想收发电子邮件的普通用户来说,电脑加网线就是 Model 。想发电子邮件?买台电脑,装上网线,问题就解决了。

  • View,也就是视图/视野,是你真正看到的,而非想象中的 Model。

  • Controller,也就是控制器,是你用来改变 Model 方式。简单的说 Controller 和 View 分别是 Model 的 输入 和 输出。

    还是刚才的例子,想收发邮件,光有电脑 (Model) 还不行。你知道你的邮箱在电脑里,但是你不知道它是什么样子。所以你还需要一台显示器 (View)。同时,你可以看到你的电脑在运行,你的邮箱在收信。但是你还想发信,你需要一块键盘 (Controller)。

  • View 和 Controller 可以是 Model 的一部分。为什么要单独把他们跟 Model 分开呢?因为 View 和 Controller 是外在的东西,只有 Model 是本质的东西。外在的东西天天变化,但很少影响本质。把他们分开比较容易维护。
    比如同样是跑 Android 系统的电脑,可以做成手机,可以做成笔记本,还可以做成机顶盒。无非就是 View 换成显示器,液晶屏,还是电视机,Controller 换成触摸屏,键盘,还是遥控器的问题。本质上其实是同一个 Model (Android 电脑)。

  • 现在回到 Web 开发的话题。你最关心什么问题呢?显然,对于不同的人,关心的问题是不同的,对他来说Model也不同。从数据库管理员的角度上看,你的数据库整个就是一个 Model。很显然,数据库的数据变化已经反映出了用户所关心的一切。在数据库管理员的眼中,你的Servelet 整个就是一个大Controller,就是把用户的请求转换成数据库查询而已。由于 Model 没有逻辑,所以整个就像一块橡皮泥,想怎么捏,就怎么捏。所以如果你得寄希望于一双灵巧的手(Controller),才能避免犯错。但手本质上是不适合重复性劳动的,所这种Model未必合适所有问题。
  • 写后台的人为了解决这个问题,只好再把数据库包装一层,即通过所谓的业务逻辑对象来读写数据。然后这些业务逻辑对象就成了Model。当然数据库管理员可能会说,我可以有逻辑啊,你可以写存储过程嘛。也有人觉得我自己建自己的Model,数据库只管存数据就行了。所以他们倾向直接把对象序列化丢服务器,或者用对象数据库。
  • 还有些人妥协一点,认为数据库也是有Model的但它是关系型(Relational)的Model,但我也有自己的面向对象(Object-Oriented)的Model,所以两个Model之间需要同步。这就是ORM(Object-Relation Mapping)。
    最后写前端的人说,我做 View 也不容易啊。我要保存中间的输入状态,要做逻辑验证逻辑等。在最终提交到服务器之前,你总不能让用户中间输错一个数据,就重启系统,整个步骤重来吧?你去银行申请服务,还得填表(Submit a Form)呢,表个还要改好几次呢。于是 View 也要有自己的 Model,这个特定的情形。
  • 更有甚至者,你的 View 根本就不是你自己开发的。比如开发 视屏播放器 (View) 的人哪管你是干什么的啊?人家只关心你给他的东西是什么格式的,这也是他的 Model,叫 ViewModel (MVVM里的VM)。一般来说,Controller 做的工作都比较简单,无非就是转转格式,做做验证。甚至有时 View 的工作也很枯燥,比如输出 JSON 或 XML。所以这些一般都由框架包办了,你只要关注 Model 也就是 核心问题 就行。

  • 在早年web开发刚刚发明的时候,html,css,js是杂糅在一起的,不利于合作开发,也显得很冗余。在当时,mvc的出现可以说是规范和改良了整个web开发的过程,使得开发效率大大提升,所有人都能够专注于某一个部分的工作而不需要分散自己的精力到各个环节。但是,随着web技术的越来越复杂,页面交互越来越多,传统的mvc已经不太适合现今的web的前端开发了(但是毫无疑问,mvc的模块分离思想是十分聪明而且正确的,在其他的开发领域他依然是一种十分重要的架构模式)。

  • 在MVC原始报告中指出:view永远不会知道用户输入,比如鼠标操作和按键。很显然,在Web前端,你无法做到这一点,因为Web的程序中,用户的输入必须通过监听窗口、文档和元素上的事件来获得。——而这些东西常常被认为是View。于是一些奇怪的认识诞生了,比如认为Controller应该是View操作Model的中介。
  • John Gossman(WPF的架构师)在他的文章中提到,Model/View/ViewModel中的View表示可见元素,按钮,窗体,图形或者GUI中更复杂的控件,它会对快捷键进行编码,并且控件自身会管理跟输入设备的交互——这在MVC中本该是Controller负责的(现代GUI环境中发生在Controller上的事情是很长的题外话……我倾向于认为它只是隐藏到后台了,它仍然存在,但是我们不需要像是1979年那样考虑那么多事情了)
  • MVC这样的结构的正确性在于,任何界面都需要面对一个用户,而Controller “是用户和系统之间的链接”。在经典MVC中,Controller要做的事情多数是派发用户输入给不同的View,并且在必要的时候从View中获取Editor来更改Model,而Web以及绝大多数现在的UI系统中,Controller的职责已经被系统实现了。下面的图片说明了这样的演进过程:

总而言之,对于MVC
- 为1979年的SmallTalk设计
- 界面和程序都由同一种语言编写
- 用户输入完全由程序编写者来处理
- View是单纯用于显示

对于MVVM
- 为2005年的WPF设计
- 界面多使用标记语言,程序则使用编程语言
- 用户输入经过UI系统底层处理和分发,多数以事件的形式被用户程序所知
- View具有独立性,能够管理部分用户输入并且自行反应(它们常常被称作控件,而非视图)

作为一个Web开发者,在二者之间做出何种选择是显而易见的。

你可能感兴趣的:(WEB项目中MVC与MVVM的思考)