Best MVC Practices

最优的MVC布局策略

  1. Model
  2. View
  3. Controller

  1.数据层

  2.视图层

  3.控制器层

Although Model-View-Controller (MVC) is known by nearly every Web developer, how to properly use MVC in real application development still eludes many people. The central idea behind MVC is code reusability and separation of concerns. In this section, we describe some general guidelines on how to better follow MVC when developing a Yii application.

尽管MVC几乎为每一个WEB开发者所知道,但是如何在真实的应用开发中合理的使用它,很多人就不能说得很清楚了。MVC的核心思想是:代码的重用性与低耦合性。在这一部分,我们简要地描述一些关键概念,以帮助你在开发YII应用的过程中能更好的使用MVC。

To better explain these guidelines, we assume a Web application consists of several sub-applications, such as

  • front end: a public-facing website for normal end users;
  • back end: a website that exposes administrative functionality for managing the application. This is usually restricted to administrative staff;
  • console: an application consisting of console commands to be run in a terminal window or as scheduled jobs to support the whole application;
  • Web API: providing interfaces to third parties for integrating with the application.

为了更准确的解释这些概念,我们假设一个WEB应用包含一定数量的子应用,例如:

  • 前端:一个面向最终用户的网站;
  • 后端:一个一般只供管理人员操作的管理应用的网站。
  • 控制台:一个由控制台命令构成的应用,运行于一个终端窗口或者作为计划任务以支持整个应用。
  • WEB API:提供给第三方接口以接入应用。

The sub-applications may be implemented in terms of modules, or as a Yii application that shares some code with other sub-applications.

子应用通常用模块的方式来实现,或者作为一个和其他子应用公用一些代码的YII应用。

1. Model

1.数据层(数据处理类文件)

Models represent the underlying data structure of a Web application. Models are often shared among different sub-applications of a Web application. For example, a LoginForm model may be used by both the front end and the back end of an application; a News model may be used by the console commands, Web APIs, and the front/back end of an application. Therefore, models

  • should contain properties to represent specific data;

  • should contain business logic (e.g. validation rules) to ensure the represented data fulfills the design requirement;

  • may contain code for manipulating data. For example, a SearchForm model, besides representing the search input data, may contain a search method to implement the actual search.

数据层承载着WEB应用的核心数据结构。数据层通常被众多的子应用所共享。例如,一个用户登录数据层很可能同时被前端和后端应用所公用。一个新闻数据层很可能被控制台命令行,WEB APIS,和其他网站前后台子应用所使用。因此,数据层

  • 应该包含可以代表特定数据的属性。
  • 应该包含商业逻辑(例如验证规则)以保证用户提交的数据符合应用设计者的要求。
  • 很可能包含操作数据的代码。例如,一个搜索数据层,除了含有搜索输入的数据,很有可能还包含实现这个搜索的方法(代码)。

Sometimes, following the last rule above may make a model very fat, containing too much code in a single class. It may also make the model hard to maintain if the code it contains serves different purposes. For example, aNews model may contain a method named getLatestNews which is only used by the front end; it may also contain a method named getDeletedNews which is only used by the back end. This may be fine for an application of small to medium size. For large applications, the following strategy may be used to make models more maintainable:

  • Define a NewsBase model class which only contains code shared by different sub-applications (e.g. front end, back end);

  • In each sub-application, define a News model by extending from NewsBase. Place all of the code that is specific to the sub-application in this News model.

有时候,按照上面最后一条所说得做的话,可能导致你的数据层十分的臃肿,因为在一个类中包含了太多的代码。而且如果这个数据层包含多套业务逻辑的话,这个数据层维护起来会相当的麻烦。例如,aNews这个数据层可能包含一个名叫getLastNews的方法,这个方法只会被前端用户所用到。同时这个数据层可能还包含一个叫做getDeletedNews的方法,这个方法只会被后端管理员用到。如果这个应用的规模很小或者中等还好,对于大型应用,以下的策略可能使你的数据层更易维护:

  • 定义一个NewsBase的数据类文件,这个文件只包含不同应用都需要用到的代码。(例如前后端);
  • 在每一个子应用中,定义一个News数据层类文件来继承NewsBase这个类。在这个News类文件中只写当前应用需要使用到得方法。

So, if we were to employ this strategy in our above example, we would add a News model in the front end application that contains only the getLatestNews method, and we would add another News model in the back end application, which contains only the getDeletedNews method.

所以,如果我们采取这个策略,应用到上面的例子的话,我们就先写这个NewsBase,然后再在前端写一个News类来继承NewsBase,在这个News类中只包含getLastNews方法,同样的方法,在后端也写一个BackNews来继承这个NewBase,在这个BackNews中只写后台管理员才用到的getDeletedNewsz这个方法。

In general, models should not contain logic that deals directly with end users. More specifically, models

  • should not use $_GET$_POST, or other similar variables that are directly tied to the end-user request. Remember that a model may be used by a totally different sub-application (e.g. unit test, Web API) that may not use these variables to represent user requests. These variables pertaining to the user request should be handled by the Controller.

  • should avoid embedding HTML or other presentational code. Because presentational code varies according to end user requirements (e.g. front end and back end may show the detail of a news in completely different formats), it is better taken care of by views.

总得来说,数据层不应该直接处理终端用户的逻辑,详细一点的说,数据层

  • 不应该使用$_GET,$_POST,或者其他相似的直接跟终端用户有关联的变量。记住,一个数据层可能被完全不同的子应用所使用,而这些子应用不可能都用相同的变量来处理用户的请求。和用户请求相关的变量应该都交给控制器来处理。
  • 应该避免嵌入HTML或者其他“显示代码”。因为显示代码根据用户请求不同而不同(例如前段和后端可能以完全不同的格式来显示新闻),而这最好交给视图层来完成。

2. View

2.视图层

Views are responsible for presenting models in the format that end users desire. In general, views

  • should mainly contain presentational code, such as HTML, and simple PHP code to traverse, format and render data;

  • should avoid containing code that performs explicit DB queries. Such code is better placed in models.

  • should avoid direct access to $_GET$_POST, or other similar variables that represent the end user request. This is the controller's job. The view should be focused on the display and layout of the data provided to it by the controller and/or model, but not attempting to access request variables or the database directly.

  • may access properties and methods of controllers and models directly. However, this should be done only for the purpose of presentation.

Views can be reused in different ways:

  • Layout: common presentational areas (e.g. page header, footer) can be put in a layout view.

  • Partial views: use partial views (views that are not decorated by layouts) to reuse fragments of presentational code. For example, we use _form.php partial view to render the model input form that is used in both model creation and updating pages.

  • Widgets: if a lot of logic is needed to present a partial view, the partial view can be turned into a widget whose class file is the best place to contain this logic. For widgets that generate a lot of HTML markup, it is best to use view files specific to the widget to contain the markup.

  • Helper classes: in views we often need some code snippets to do tiny tasks such as formatting data or generating HTML tags. Rather than placing this code directly into the view files, a better approach is to place all of these code snippets in a view helper class. Then, just use the helper class in your view files. Yii provides an example of this approach. Yii has a powerful CHtml helper class that can produce commonly used HTML code. Helper classes may be put in an autoloadable directory so that they can be used without explicit class inclusion.

视图层的任务是根据用户的请求来呈现数据层的内容,视图层

  • 应该主要包含“显示代码”,例如HTML,和简单的PHP代码,作为穿插,格式化数据或者发送数据。
  • 应该避免直接执行数据库操作语句,这样的操作最好放在数据层。
  • 应该避免直接去操作用户请求相关变量如$_GET,$_POST,这是控制器的活。视图层应该专注于显示或者布局从控制器层或者数据层拿过来的数据,而不是去试图操作用户请求变量或者数据库。
  • 可能会直接地操作数据层或者控制器层的属性或者方法,但是这些只能在呈现数据的前提之下。
  • 布局:公共展示部分(例如页头和页脚)可以放在layout视图中。
  • 部分视图:使用部分视图(不在公共展示部分),以重复利用某“显示代码”。例如我们可以使用_form.php部分视图来提交数据创建业务和数据修改业务中得数据层表单。
  • 挂件:如果很多逻辑都需要展示一个“部分视图”,那么我们可以将这个“部分视图”转换为一个“挂件”,这个挂件的类文件就是放这个逻辑的最好的地方。对于生成很多HTML标记的挂件,最好是使用特定的视图文件来包含这些标记。

3. Controller

3.控制器

Controllers are the glue that binds models, views and other components together into a runnable application. Controllers are responsible for dealing directly with end user requests. Therefore, controllers

  • may access $_GET$_POST and other PHP variables that represent user requests;

  • may create model instances and manage their life cycles. For example, in a typical model update action, the controller may first create the model instance; then populate the model with the user input from $_POST; after saving the model successfully, the controller may redirect the user browser to the model detail page. Note that the actual implementation of saving a model should be located in the model instead of the controller.

  • should avoid containing embedded SQL statements, which are better kept in models.

  • should avoid containing any HTML or any other presentational markup. This is better kept in views.

In a well-designed MVC application, controllers are often very thin, containing probably only a few dozen lines of code; while models are very fat, containing most of the code responsible for representing and manipulating the data. This is because the data structure and business logic represented by models is typically very specific to the particular application, and needs to be heavily customized to meet the specific application requirements; while controller logic often follows a similar pattern across applications and therefore may well be simplified by the underlying framework or the base classes.

控制器是粘合数据层和视图层和其他组件的胶水。控制器负责处理用户的直接请求,因此,控制器

  • 可以处理$_GET,$_POST和其他代表用户请求的变量。
  • 可以创建数据层实例,并管理他们的生存周期。例如在一个典型的更新操作中,控制器可能最先创建数据层的实例;接下来接收来自用户POST过来的数据;成功更新数据之后,控制器层可能会将用户导向详情页。注意,实际的执行数据更新的操作应该在数据层完成,而非在控制器层。
  • 应该避免包含SQL语句的嵌入,最好把他们放置在数据层。
  • 应该避免包含任何HTML或者其他的“显示标记”,最好把他们交给视图层来处理。

在一个优秀的比较优秀的MVC应用中,控制器层同层非常精简,只包含数十行代码;而数据层通常会非常臃肿,他们包含了展示和操作数据的代码。这时因为特定的应用所要求的数据结构和数据层需要处理的商业逻辑都不相同,因而需要专门定制以满足需求。而控制器层通常依据一些应用间比较相似的逻辑,因此被框架或者基类预先简化了。

Best MVC Practices(最优的MVC布局)的更多相关文章

  1. MVC视图展现模式之移动布局解析-续集

    网站就必须用响应式布局吗?MVC视图展现模式之移动布局:http://www.cnblogs.com/dunitian/p/5213787.html demo:http://pan.baidu.com ...

  2. Best MVC Practices 最佳的MVC实践

    Although Model-View-Controller (MVC) is known by nearly every Web developer, how to properly use MVC ...

  3. ASP.NET MVC 5 02 - ASP.NET MVC 1-5 各版本特点

    参考书籍:<ASP.NET MVC 4 高级编程>.<ASP.NET MVC 5 高级编程>.<C#高级编程(第8版)>.<使用ASP.NET MVC开发企业 ...

  4. MVC自学系列之三(MVC视图-Views)

    View的约定 1.根据约定,Views目录下包含着每一个与Controller同名但是没有像Controller后缀的文件夹:因此对于控制器HomeController就对应在views目录下有个目 ...

  5. 从一个简单案例上手Spring MVC,同时分析Spring MVC面试问题

    很多公司都会用Spring MVC,而且初级程序员在面试时,一定会被问到这方面的问题,所以这里我们来通过一个简单的案例来分析Spring MVC,事实上,我们在培训中就用这个举例,很多零基础的程序员能 ...

  6. System.Web.Mvc.dll在各个版本MVC中的文件位置

    the default folder would be like the following: MVC 5 C:\Program Files (x86)\Microsoft ASP.NET\ASP.N ...

  7. Spring 4 官方文档学习(十一)Web MVC 框架之配置Spring MVC

    内容列表: 启用MVC Java config 或 MVC XML namespace 修改已提供的配置 类型转换和格式化 校验 拦截器 内容协商 View Controllers View Reso ...

  8. 像asp.net Mvc一样开发nodejs+express Mvc站点

    像asp.net Mvc一样开发nodejs+express Mvc站点 首先,我是个c#码农.从事Mvc开发已然4个年头了,这两年前端MVC的兴起,我也跟风学了一些,对前端的框架也了解一些,angu ...

  9. Spring mvc系列一之 Spring mvc简单配置

    Spring mvc系列一之 Spring mvc简单配置-引用 Spring MVC做为SpringFrameWork的后续产品,Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块 ...

随机推荐

  1. Git 基本命令有哪些

    Git 相关命令 git init 初始化一个项目 git clone 利用url 从远程clone下来一个项目 git status 查看当前项目修改状态 git log 查看日志 查看历史记录 g ...

  2. Linux 安装 mysql 并配置

    1.下载 下载地址:http://dev.mysql.com/downloads/mysql/5.6.html#downloads 下载版本:我这里选择的5.6.33,通用版,linux下64位 也可 ...

  3. JVM菜鸟进阶高手之路十一(eden survivor分配问题)

    转载请注明原创出处,谢谢! 问题 这个Xmn设置为1G,,我用jmap -heap 看,这个Eden From To怎么不是一个整8:1:1的关系呢? 我看内存分配还是没变,我Xmn1g,感觉From ...

  4. ACM-ICPC北京赛区(2017)网络赛_Minimum

    题目9 : Minimum 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 You are given a list of integers a0, a1, -, a2^k ...

  5. php字符的替换,截取,指定查找

    <?php/** * Created by 郭鹏. * User: msi * Date: 2017/9/27 * Time: 14:17 *///随机数生成器echo rand();echo ...

  6. String.getBytes(),源码之下,了无秘密

    @Deprecated public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin) { if (srcBegin ...

  7. MXNet--DMLC-Core代码解读与宏

    MXNet--DMLC-Core代码解读与宏 dmlc-core是Distributed (Deep) Machine Learning Community的一个基础模块,这个模块用被应用到了mxne ...

  8. Excel更改单元格格式后无效

    问题描述: 比如修改了数据的自定义显示格式(日期显示 yyyy"年"m"月",手机号分段000-0000-0000),应用后发现只有部分生效,或者都不生效,再检 ...

  9. OpenVPN CentOS7 安装部署配置详解

    一 .概念相关 1.vpn 介绍 vpn 虚拟专用网络,是依靠isp和其他的nsp,在公共网络中建立专用的数据通信网络的技术.在vpn中任意两点之间的链接并没有传统的专网所需的端到端的物理链路,而是利 ...

  10. 一张图理清ASP.NET Core启动流程

    1. 引言 对于ASP.NET Core应用程序来说,我们要记住非常重要的一点是:其本质上是一个独立的控制台应用,它并不是必需在IIS内部托管且并不需要IIS来启动运行(而这正是ASP.NET Cor ...