MVC新手指南

MVC新手指南

2010-04-06 09:54:23 18839 次阅读 0 条评论

本文感谢东西提供 模型-视图-控制器(MVC)可能是近年来网络编程圈子里最常被提及的模式之一。目前与网络应用开发沾边的人听到和看到这个字母缩写的次数肯定不下百次。 今天,我们将详细阐述一下MVC的含义,以及它变的如此流行的原因。

古老的历史…
MVC不是一种设计模式(design pattern),它是一种架构模式(Architectural pattern),用以描述应用程序的结构以及结构中各部分的职责和交互方式。
它最先是在1979年的时候第一次被人提出,不过,当时环境有些不同,网络应用的概念在当时还不存在。提姆·伯纳斯李在上世纪九十年代初期的时候播种下了万维网(WWW)的种子,并永远的改变了世界。目前我们在网络开发中所采用的这种模式实际上是原版模式的一个改编版。
这种架构模式的疯狂流行是由于两个极其流行的开发框架将这种模式包含了进来,它们是:Struts  Ruby on Rails。这两个开发框架给稍后诞生的数百框架打上了深深的烙印。

网络应用中的MVC模式
模型-视图-控制器架构模式背后的思想非常简单:我们的应用程序中必须区分下面这些职责:

应用程序被分成了三个主要的部分,每个部分负责掌管不同的任务。下面让我们看看详细的解释以及一个例子。
控制器
控制器掌管着用户的请求(当用户点击图形用户界面(GUI)上的元素执行操作时,控制器会收到HTTP GET或者POST请求)。它的主要功能就是调用并协调需要的资源/对象来执行用户请求。通常控制器会为任务调用合适的模型,以及选择合适的视图。 模型
模型是指运用于数据之上的数据规则和数据内容,它一般对应于应用程序所要管理的对象。在软件系统中,任何事物都可以被抽象成可以对其以某种方式进行处理的数据模型。应用程序中的用户,信息以及图书是什么?它们只是一堆必须按照对应规则处理的数据(日期不能是未来的日期,电子邮件有特定的格式,名字的长度不能超过多少字符等等)

模型给控制器提供了一个用户请求内容对应的数据表达(比如信息,书,相册)。不管我们如何向用户展示,这个数据模型都不会变。这也是我们为什么可以随意选择使用哪个视图来展示数据的原因。
模型包含我们应用程序逻辑中最重要的组成部分,这些逻辑运用于我们要处理的问题过程中。控制器更多的是包含应用程序自身的内部组织逻辑(更像管家)。
视图
视图提供了展示模型数据的不同方式。它可能是数据填充的模板。视图可以有多个,而控制器则决定使用哪个视图。一个网络应用通常由许多控制器,模型和视图组成。控制器可以被看成是一个主控制器,用于接收用户的所有请求,然后在调用特定的控制器来处理不同的情况。
让我们看一个例子
现在,假设,我们正在开发一个在线书店。用户可以进行如下操作:查看图书。注册,购买,往当前订单添加物品,创建和删除图书(如果他有管理员权限的话)。现在让我们看看当用户单击“幻想”门类来查看该门类下有哪些书时会发生什么情况。
我们会有一个特定的控制器来处理所有与图书相关的操作(查看,编辑,创建等操作)。这个例子中,我把该控制器命名为 books_controller.php。我们也会有一个模型(比如 book_model.php)来处理数据和与商店中图书物品相关的逻辑。最后我们还有一些视图来展示数据,比如图书清单,一个编辑图书的页面等等。
下面这幅图展示的是用户发出的查看请求是如何处理的:

控制器(books_controller.php)以HTTP GET或者POST的方式接收到用户的请求[1](我们也可以有一个主控制器,比如index.php 来接收请求,然后它再调用ooks_controller.php)
控制器检查请求以及对应的参数,然后调用模型(book_model.php),请求模型返回幻想类的图书[2]。模型负责从数据库中调取信息 [3],如有需要它可以加入过滤和逻辑,然后返回图书列表。
控制器使用恰当的视图来将这些数据展示给用户[6-7],如果用户还选择了特定皮肤,对应的视图文件也会被选上等等。
MVC的好处是什么
我们使用MVC的一个最明显好处就是它将视图展示和应用逻辑清晰的分离开来。
对不同用户以及不同设备类型的支持一直是当下的一个常见问题。来自台式电脑和手机的请求所得到的视图应该是不相同的。模型会返回完全相同的数据,但是不同的地方是控制器会选择使用的视图文件来展示数据(我们可以把它看作是不同的模板)。
除了将视图从业务逻辑中分离开外,MVC的分离也降低了大型应用设计的难度。代码也更具结构性,因此也更容易维护,测试和重用。
但是为什么要框架呢?
当你使用一个框架时,MVC的基本结构已经包含在其中,你只需对这些结构进行扩充,将你的文件遵照MVC的模式放置到合适的目录中去。而且它也提供许多现成并且经过完全测试的功能。
以CakePHP最为MVC框架的例子。你一旦安装好以后,你会发现它包含三个主要的目录:
    * app/     * cake/     * vendors/
APP文件夹是放置你应用程序文件的地方。这是你开放应用程序的地方。
Cake文件夹是Cakephp的文件存放位置以及开发的地方(框架的重要功能就在里面)
Vendors文件夹是用来存放所需要的第三方PHP库文件的位置。
你的工作文件夹(APP文件夹)又有下面这些结构:
    * app/           config/           controllers/           locale/           models/           plugins/           tests/           tmp/           vendors/           o views/           o webroot/
现在你需要将你的控制器放置到controllers目录下,你的模型放置的models目录下,而视图文件则在views目录下。
一旦你熟悉了框架,你就能在你需要修改和创建代码时,知道应该在哪里动手。这种文件组织方式让维护容易上不少。
以框架为例 因为这个教程并不打算教你如何使用CakePHP制作一个应用程序,我们只是用它来展示一下模型,视图和控制器的演示代码,并对使用MVC框架所带的好处做一个评论。这些代码都是简化了的,并不适合实际的应用。
我们之前已经有一个在线书店,并且有一个好奇的用户想查看幻想门类下所有图书的清单。我们说过控制器会接收请求,然后协调控制器的操作。
因此当用户点击时,浏览器会请求下列网址:
www.ourstore.com/books/list/fantasy
CakePHP 的URL地址形式是/控制器/操作/参数1/参数2.这里的操作是控制器内调用到调用的函数。之前老的url网址则是
www.ourstore.com/books_controller.php?action=list&category=fantasy
控制器
使用CakePHP框架,我们的控制器的样子像下面这样:
   <?php            class BooksController extends AppController {            function list($category) {          $this->set(‘books‘, $this->Book->findAllByCategory($category));          }        function add() { ... ... }          function delete() { ... ... }        ... ... } ?> 
很简单,是吧。这个控制器会被保存成 books_controller.php,并放置在/app/controllers目录下。它包含一个列表(list)函数,用以执行我们例子中的操作,它也可以包含其他与图书相关的操作(像添加新图书,删除新图书)
框架为我们提供了许多内容,罗列所有图书只需一行代码。我们在基本的控制器行为中定义的有一个基础类,我们已经继承了。(AppController继承自Controller的)
在list操作中,我们需要做的就是调用模型获取数据,然后选择合适的视图文件来将数据展示给用户。下面要我们解释一下过程。
this->Book是我们的模型,而下面这段代码
$this->Book->findAllByCategory($category)
则是在告诉模型返回所选门类下的图书列表
下面的Set方法
$this->set(‘books‘, $this->Book->findAllByCategory($category));
是告诉控制器将数据传输给视图。它将模型返回的数据以books的变量传输给视图,然后视图中就可以访问该变量了。
现在我们需要渲染视图,如果你是使用默认视图,CakePHP会帮你自动完成。如果你需要使用其他视图,你则需要使用render方法来具体声明
模型
模型非常简单。
   <?php          class Book extends AppModel {            }          ?> 
为什么是空的?因为它从基础类继承了一些必须的功能,我们只需遵循CakePHP的命名规范,然后框架就会自动帮你完成其他事情。比如。通过名字,CakePHP知道,这个是BooksController中使用的模型。然后会自动访问数据库中一个叫books的数据表。
这个定义,我们的book模型就具备从数据库中读取,删除和保存数据的能力。
这段代码应该保存成books.php,并放置于/app/models文件下。
视图
我们现在需要做的事情就是为list操作创建一个视图(至少是一个)。这个视图将使用HTML代码,并且还包含一些PHP代码来遍历模型提供的 books数组。
   <table> <tr> <th>Title</th> <th>Author</th> <th>Price</th> </tr>          <?php foreach ($books as $book): ?> <tr> <td> <?php echo $book[‘Book‘][‘title‘]; ?> </td> <td> <?php echo $book[‘Book‘][‘author‘]; ?> </td> <td> <?php echo $book[‘Book‘][‘price‘]; ?> </td> </tr> <?php endforeach; ?>          </table> 
我们已经看到了,视图文件并不生成一个完成的页面,它只是一段HTML代码。这是因为CakePHP提供了定义页面布局的方法,而视图则会被插入到布局中。在创建这些HTML片段时,框架也提供一些助手(helper)对象来帮我们完成常见的任务(插入表单,链接,Ajax或者 JavaScript) 我们将这个默认视图保存为list.ctp(list是操作的名称,而ctp是指cake模板),然后将它放置在 /app/views/books下(之所以在books目录下,是因为它是Book控制器的操作)。
至此在CakePHP的帮助下,这三部分都完成了。
结论
我们已经学习了当今最常用的架构模式MVC,我们需要注意,当我们在编程界提及的模式时,我们指的是可以用来解决手中问题的灵活架构。我们会发现实际使用会给我们看到的结构带来变动。但最为重要的是,这种模式会帮助我们气息的区分程序各部分的职责,便于程序维护,代码重用以及测试。
我们已经见识了使用MVC框架的好处,它给我们提供了一个基本的MVC骨架,以及许多有用的功能,提高了我们的效率,让开发过程更加轻松。

时间: 2024-10-12 15:02:29

MVC新手指南的相关文章

爱上MVC~业务层刻意抛出异常,全局异常的捕获它并按格式返回

对于业务层的程序的致命错误,我们一直的做法就是直接抛出指定的异常,让程序去终断,这种做法是对的,因为如果一个业务出现了致命的阻塞的问题,就没有必要再向上一层一层的返回了,但这时有个问题,直接抛异常,意味着服务器直接500了,前端如何去显示,或者如果你是API的服务,如果为前端返回,如果是500,那直接就挂了,哈哈! 下面是在MVC环境下优化的全局异常捕获代码(非API) /// <summary> /// 全局异常捕获 /// </summary> public class Glo

ASP.NET MVC 使用Remote特性实现远程属性验证

RemoteAttribute是asp.net mvc 的一个验证特性,它位于System.Web.Mvc命名空间 下面通过例子来说明 很多系统中都有会员这个功能,会员在前台注册时,用户名不能与现有的用户名重复,还要求输入手机号码去注册,同时手机号码也需要验证是否重复,下面是实体类 /// <summary> /// 会员 /// </summary> public class Member { public int Id { get; set; } [Required(Error

Asp.Net MVC及Web API框架配置会碰到的几个问题及解决方案 (精髓)

前言 刚开始创建MVC与Web API的混合项目时,碰到好多问题,今天拿出来跟大家一起分享下.有朋友私信我问项目的分层及文件夹结构在我的第一篇博客中没说清楚,那么接下来我就准备从这些文件怎么分文件夹说起.问题大概有以下几点: 1.项目层的文件夹结构 2.解决MVC的Controller和Web API的Controller类名不能相同的问题 3.给MVC不同命名空间的Area的注册不同的路由 4.让Web API路由配置也支持命名空间参数 5.MVC及Web API添加身份验证及错误处理的过滤器

Swagger+ springfox +Spring mvc

简介 Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步.Swagger 让部署管理和使用功能强大的API从未如此简单.这一次我将从零开始搭建一个工程来演示如何在Spring mvc中整合Swagger生成Restful接口文档. 新建工程 我们新建一个Maven工程,并添加Web Facet,工程结构如下图所

MVC下微信企业号网页应用开发调用JSSDK接口不成功问题

在MVC下进行企业微信里的网页应用开发,前台页面中为了调用图像接口,使用了JSSDK.按照官方文档进行了正确配置. 现象:WEB开发工具调试一切正常,但从手机企业微信应用进入页面后接口调用无效(这个页面是从一级页面链接过来的),开了调试模式后,显示config:ok.说明配置无误.经过反复检查,终于发现问题所在. 原因:在一级页面(http://xx.xxx.xxx/main/index)中的链接是使用htmlhelper来写的,即@Html.ActionLink("测试接口",&qu

ASP.NET MVC与CSRF(跨站脚本)攻击

CSRF 一 何为CSRF CSRF(Cross-site request forgery跨站请求伪造,也被称成为"one click attack"或者session riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用.需要注意的是,CSRF与XSS的区别,CSRF是其他网站进行对你的网站的攻击. 关于CSRF的详细信息请看:https://baike.baidu.com/item/CSRF/2735433 二 CSRF的危害 对CSRF进行简单了解后,我们先来看看

95后实习生的远程办公体验(asp.net mvc\C#技术栈)

这个月我们做了一件别人看起来很疯狂的事情,就是让一批95后的实习生实行远程办公,效果还不错,于是写此文总结一下. 其实认真算算,我自己的远程工作经验有十年了吧,在北京工作的时候天气不好就申请在家办公,在硅谷的时候每周有三天在家办公,两天去办公室办公.所以我也算得上是远程办公的老司机了吧. 不过,我之前都是对有多年工作经验的老司机才实行远程办公,还从来没有对还未毕业的实习生实行过.老实说,不敢啊,也不放心,况且我在cnblogs博客园呆了十年,还真没见过对还未毕业的实习生实行过远程办公的. 那为什

视图框架:Spring MVC 4.0(1)

目录 一.表单标签库 1.1.简介 1.2.常用属性 1.3.form标签与input标签 1.4.checkbox标签 1.5.radiobutton标签 1.6.password标签 1.7.select标签 1.8.option标签 1.9.options标签 1.10.textarea.errors标签 1.11.hidden标签 1.12.radiobuttons 单选列表与checkboxs复选列表 二.视图解析器 2.1.ViewResolver视图解析器 2.2.链式视图解析器

Spring MVC HTTP请求数据绑定

package com.springmvc.controller; import com.springmvc.model.UserInfo; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.stereotype.Controller; import org.springframework.uti