2.Rails应用程序的架构

Rail的有趣点之一是它对你的web应用程序架构实施了一些强制性规定。令人惊讶的是,这些规定反而能让你很容易地创建应用程序-非常地容易。让我们看看为什么?

2.1模型,视图和控制器

追溯至1979年,Trygve Reenskaug 提出一种开发交付式应用程序的新架构。在他的设计中,应用程序被分为三种类型的组件:模型,视图和控制器。

模型负责维护应用程序的状态。有时候这种状态的持续时间是短暂的,仅存在与用户的交互过程中。但有时候这状态又是持久的,它存储在应用程序之外,经常是在数据库。

一个模型通常不只是数据;它还执行了应用在数据上的规则。例如,若规定少于$20的订单不予折扣,则模型将实行此规则。这是很有意义的。在模型中贯彻这些业务规则,我们能确保在应用程序中数据的有效性。 因而模型扮演着数据检查及其数据存储双重角色。

视图负责产生一个用户界面,其通常是基于模型数据。例如,一个网上商店在分类中显示一列商品。这些列表通过模型被访问,但它是作为一个视图(此视图从模型中读取列表)展示在终端用户面前。虽然根据不同的输入数据可以在用户面前展示不同的视图,但视图本身无法改变这些数据,它要做的唯一工作就是显示数据。为了达到不同目的,多个视图也可能存取同一个模型数据。对在线书店,在分类页面有个视图用于显示产品信息,同时也有若干视图供管理员新增和编辑产品。

控制器从外部世界接收事件(通常是用户的输入),和模型进行交互,并给用户显示适当的视图。

这三种,模型,视图,和控制器――形成了大家熟悉的MVC架构。

MVC最初来源于传统的GUI应用程序,在那里开发人员发现分离关注点可以减少耦合,而这反之又可以使代码变得容易编写和维护。每个概念和动作将在一个众所周知的位置被表达。使用MVC就象建造已搭好钢架的摩天大楼――只需进一步填充剩余零件。

在软件开发世界中,我们经常在往前赶路时忽视了过去好的想法。当开发者第一次开始建造web应用程序,他们退回到写集成电路程序了,在一个大的代码块中混杂着展现,数据存储,业务逻辑,和事件处理。但是想法慢慢又回到了原来上了,人们开始把已经存在了20几年的MVC思想应用在web应用程序的架构上。这样的结果就出现了WebObject,struts和Java Server Faces 等框架。所有的这些都是基于MVC的思想上的。

Ruby on Rails也是一个MVC框架。Rails强调应用程序的模型,视图和控制器之间的分离――在应用程序执行的时候把它们组织在一起。关于Rails有趣的是它把这些组织在一起是基于智能的默认设置而不需要你编写任何的外部配置文件。这就是Rails哲学的一个例子,约定俗成优于配置。

在一个Rails应用程序中,接收到的请求首先被发送到一个路由器上,它用于决定在此应用程序中,请求将发送至哪里,及如何解析请求本身。最终,这个过程在控制器代码中决定了一种相应方法(在Rails中通常称为“动作”)。动作将根据请求查找数据,它可以和模型进行交互,并且它也可能导致其它的动作被执行。最后这个动作给视图准备了信息,呈递给用户。

在下一页的图2.2上显示了Rails是如何接收一个请求的。在这个例子中,假设在分类中显示产品,用户刚刚点击了其中一个产品的“Add To Cart”按钮。这个按钮返回了一个http://my.url/store/add_to_cart/123链接给我们的应用程序,123是我们选择的产品的内部编号。

路由器组件接收了请求并把它分为若干部分。在这个简单的例子中,路径(指的是/store/add_to_cart/123)的第一部分store作为控制器的名称,第二部分add_to_cart作为动作的名称,最后部分123,约定俗成为内部变量称为编号。根据分析的结果,路由器在控制类StoreController中调用了add_to_cart方法。

add_to_cart()执行了用户的请求。从而它查找到了当前用户的购物车,并要求模型查找产品编号为123的信息,最终把产品添进购物车。

现在购物车里多了个新产品,我们要把它显示给用户看。控制器安排视图从模型中取得了购物车的对象,并且调用视图代码。在Rails中,这个调用通常是隐含的。再次依据约定把视图和已知动作连接起来。


以上所述就是一个MVC web应用程序。通过一些约定以及功能性的适当分割,你将发现你的代码更易于操作,你的程序更易于扩展和维护。这看起来是一个良好开端。

如果MVC仅仅涉及如何通过一特定途径分割你的代码这个问题,你可能会质疑为什么还需要象Ruby on Rails这样的框架。答案很简单,Rails为你处理所有低级别的事务,包括所有冗长细节,使你能集中精力关注应用程序的核心功能。