转自:http://hi.baidu.com/waytofall/blog/item/dad928f9d042b65f242df222.html
Ruby On Rails 中MVC 架构浅谈
MVC 最早是由Trygve Reenskaug(似乎是一位挪威人,奥斯陆大学教授,自称是一位自学成才的职业软件工具开发者)提出的设计模式。它起初被应用于用户界面的开发,而广泛应用于web application 的开发却只是近几年的事情。MVC 作为一种设计模式可以被所有框架和平台所使用,并不是Ruby On Rails专属,那么为什么MVC 在Ruby On Rails 中显得格外重要?原因是Ruby On Rails用固定的目录结构(当然也许可能还有其他的一些笔者并不了解的机制)“强制”了开发人员必须遵循MVC 的设计模式。Ruby On Rails 是一种“惯例重于配置”的开发框架,所以省去不必要的配置累赘而专心于应用程序的开发显然是一件大快朵颐的事情。当然,MVC 也在web 应用程序开发中有其优越性,所以当下RubyOn Rails 才如此受追捧。
关于MVC,本文只是浅谈一下MVC 是如何被运用在Ruby On Rails 框架中的,所以论述都针对最简单的一些Rails 开发的场景。这样做的好处就是可以让对MVC 和Ruby On Rails 都不太熟悉的初学者尽快对他们有一个大体的认,从而可以快速投入到体验Ruby On Rails 开发乐趣的实践中。
MVC introduction
首先还是要赘述一下MVC 到底是什么。
M:Model
V:View
C:Controller
Model 层是和数据库紧密联系的一层,也是整个应用程序设计的核心。Model可以理解为所有应用程序中的对象以及封装在其中的各种操作。Ruby On Rails框架将面向对象的思想贯穿始终,所以Model 当然所有操作所围绕的中心。
View 是与用户打交道的一层,实际上就是一些嵌入了ruby 代码的html 页面。用户通过View 对web 应用程序进行一些操作的申请,并通过View 查看操作的结果。
Controller 层可能是比较难以表述的一层,通常的说法是用于连接Model 层和View 层。Controller 可以理解为一些动作的集合,这些动作是为View 与Model之间进行交互(View 向Model 提出数据的申请,Model 向View 返回数据)进行服务的,Controller 同时也可以对这些数据进行处理。更多具体的实现问题将放在后面讲。
Why MVC?
通过以上的表述,读者可以对MVC 有一个概括性的认识,但是对MVC 的优越性可能认识并不充分,所以我会讲一下MVC 的好处。
Web 应用程序的本质就是用户通过网页对网站的信息进行各种各样的操作,有时是读,有时是写,有时可能是更复杂的操作,比如将信息分类排序或进行一些处理再返还给用户。而所有的这些信息都是存储在服务器的数据库当中的(极少量会存储在用户本地如cookie)。这也就意味着,web 应用程序的开发的实质就是提取用户的行为,从数据库中读取信息并返还给用户,周而复始。如果仅仅从这个层面上来说,web 应用程序的开发就是一些对用户行为的捕捉和数据库操作以及显示信息的集合。但是如果把所有这些操作都放在一个文件中不但组织起来麻烦,可读性差,结构混乱,而且不利于代码的复用。于是MVC 的架构就是用于将这些混乱的代码分隔开从而实现使结构更清晰、使代码更易读并提高其复用性和抽象性的作用。
Model 是抽象出来的类,也是数据的实体。View 负责提取用户的行为并向用户显示数据。而Controller 负责把他们联系起来,使M-V 能高效地协调工作。
How Rails join them together
至此,读者对Model 和View 都有了比较深刻的理解,但是对于Controller可能都比较迷茫。关于Controller 到底是怎么把M 和V 联系在一起的也很模糊。这个章节就会对这个问题做重点描述。首先,让我们先看看Rails 是如何运行一个web 应用程序的吧。
在Rails 的工程文件夹中,有一个app 目录,用于存储所有M-V-C 代码。Model目录存储Model,Controller 目录存储Controller,View 目录存储View。在View目录中还会有很多子目录,这些子目录名都对应一个Controller。而这些子目录中存储着很多View , 这些View 有都对应相应的Controller 中的一个action(Controller 就是由一个一个action 组成的)。
当我们打开一个Rails 的页面时,机制实际上是这样的:服务器调用某个Controller 中的action,并打开与这个action 相对应的View。对应action 中的变量可以为其View 所用。这些变量从哪里来?
让我们再进一步地讲一下Model。之前曾讲过,Model 实际上就是一些类以及对应于这些类的操作。而这些类又作何用?事实上在大部分时候,Model 的每一个类都对应数据库中的一个表。如果打开Model 文件,你无法看到关于类中属性的定义,这些属性在哪?答案是数据库。Rails 框架会根据数据库中的列自动获得某个Model 的属性。所以Model 与数据库的联系是如此紧密。
知道了这些之后,接着回答之前的问题:action 中的变量来源于Model。这也是Controller 之所以可以联接M 和V 的另一个原因:Controller 可以调用Model的对象和其方法。
让我们总结一下MVC 工作的机理:Controller 从View 中接受请求,访问相应Model 中的实体,调用Model 中的方法将数据处理好返回给View,View 再负责显示这些数据,仅此而已。
如果以上还不够浅显,你可以想象成在餐馆中吃饭的场景:顾客向服务员点菜,服务员根据顾客点的菜让厨师烹调,服务员再把菜上到顾客的饭桌上。顾客是View,服务员是Controller,厨师是Model。