Microsoft 2013 新技术学习笔记 三

什么是代码结构的组织?
asp.net MVC 5 默认建立出的几个目录的标准含义分别以下:html

  • Controllers目录存放MVC模式中的Controler
  • Models目录存放MVC模式中的Model
  • Views目录存放MVC模式中的View

除此外还有Content(存放资源文件,如CSS、图片)、Scripts(JS脚本文件)等目录是有标准含义的,有标准含义也就是说有非标准含义,你能够遵循这些标准含义也能够定义本身的非标准含义,好比:前端

  • asp.net MVC 5 中的Controller无非是继承system.web.mvc.controller的类而已,你能够把这个class放在其余目录甚至另一个Project中。
  • asp.net MVC 5 的Model,常见作法是将它独立在一个Class Lib类型的Project中
  • asp.net MVC 5 的View默认为Razor引擎,在默认的规则中用Views目录存放全部的视图,你能够经过修改规则来将视图放在其余目录中,或者你用其余的视图引擎甚至自定义视图引擎

这就是我所谓的代码结构的组织,本质上其实就是MVC模式(在看MVC各类理论的时候注意一个心态:MVC模式自己也是发展变化的,每一个具体的MVC模式的实现(好比asp.net mvc)或多或少都在理论的基础上作了修改,和理论不能彻底吻合上很正常,我在学习之初太过死板,在这方面纠结了好久时间)在asp.net MVC中的实现,固然远没有上面所述的仅仅是几个目录的分类这么简单,好比Model,若是仅仅是把它独立在一个Class Lib中的话,仔细想一想,咱们之前不都是这么作的吗?web

有个PHP平台的框架YII所遵循的一些MVC实践原则我以为是总结的比较实用的(如下内容是这些实践内容的核心,部分为我本身对原文的理解加变化):数据库

模型(Model)用于表示底层数据结构,常常在整个应用的不一样部分共享,有些模型在先后台、API中都会用到,因此一个Model应该遵循的指导原则有:后端

  • 包含属性用于描述特定的数据
  • 应该包含业务逻辑,以确保数据可以知足表现的须要
  • 应该包含数据操做的代码,好比数据存储、检索
  • 确保在不一样的环境中都可实用,好比B/S环境、控制台应用或者做为单纯的API
  • 不该该出现HTML代码,负责表现的代码应该放到view文件中(这点是WebForm时代为了实现动态响应而常常这么处理的,而如今咱们有Javascript框架能够选择,如JQuery)

在上述指导原则下,可能会写出很是庞大的Model类(过多数据操做,业务逻辑代码包含其中)。这种状况下,建议进一步抽象,提炼出一个基类,包含最通用的功能,而后前端、后端和API在用到时候,将各个子应用才相关的逻辑放到基类继承出来的子类里面。微信

视图(View)主要就用于前端表现的代码:数据结构

  • 包含HTML,以及全部负责表现的代码,能够出现.net语法,可是只用于遍历数据、格式化数据(在asp.net mvc + JQuery环境中,用JQuery语法来遍历、格式化、构造Html呈现数据而不用.net语法)
  • 不该该包含DB请求
  • 仅关于表现,布局等和页面呈现有关的业务出如今View中,用户的请求数据应该由Controller和Model负责处理
  • 若是必要,能够访问Model和Controller的属性,不过这是为了知足表现的须要(asp.net mvc 5 默认建立的view就是直接访问Model的属性来呈现数据的,老实说这让我很Confuse<困惑、糊涂>:MVC模式自己不是为了解耦的吗?且不少说法都是视图都是经过Controller来与Model关联而不是直接与Model关联。在asp.net mvc + JQuery环境中,全部视图经过JQuery访问Controller来得到返回数据以呈现,也经过JQuery访问Controller来修改数据)

可使用诸如布局、部分视图等框架特性来最大程度重用View的代码。mvc

控制器(Controller)是将模型、视图和其余组件组装在一块儿造成一个应用的粘合剂。控制器直接负责处理终端用户的请求。框架

  • 处理终端用户发出的GET或POST请求,GET用来获取数据,POST用于修改数据
  • 建立模型,并决定一个模型对象的生命周期
  • 不该该出现SQL语句,数据库请求应该放到Model中(在WebForm的实践作法中,咱们建立了一堆的API、方法、函数,不少也没有出现SQL语句,在考虑重构时这很让我抓狂:什么样的代码应该放在Controller中,什么样的代码应该放在Model中,即使有了这个原则以后也是)
  • 不该该出现HTML代码,而应该将其放入到View中

在一个设计良好的MVC应用中,控制器是很是轻量级的,常常只有几十行代码的样子;而Model老是很是复杂并且庞大,包含了全部的用于表现的数据及其操做方法。这是由于由数据结构和业务逻辑组成的模型对每一个应用来讲,都是独特的,须要大量的定制化工做来知足应用的需求;控制器的逻辑常常遵循一个特定的套路,在各个应用中都差很少,所以能够被框架底层代码极大程度地简化(也就是说不是控制器代码少,而是Web开发框架已经都抽象出来而且都帮你作好了,这也 就是框架的价值和可以实现快速开发的缘由)。asp.net

遵循以上代码结构组织实践,能够有一个基于asp.net mvc 5构建的Web Application,这个project主要处理Controller和View,关于Controller的实践原则以上四条是远远不够的,Controller的做用是经过调度来达到控制输出(视图或数据)的目的(当咱们说这句话时,实际上指的是Controller的Action的实践原则。另注意:这里说起的调度和控制两个词不是技术术语,就是通俗语言的说法而已),举例来讲:

  • MVCStore示例将身份验证做为一个AuthenticationController,此控制器内不一样的方法(Action)可实现不一样的身份登陆(想象一下:AD登陆、Form登陆,这是企业内部应用常见的两种身份验证方式,我最近参与的一个对公网的系统还涉及到与微信登陆的集成),代振军有篇博文对MVCStore的这种作法作了不错的分析,由此我总结的一个Controller开发原则(出发目的是用来应对让我抓狂的"到底哪些代码放入Controller,哪些代码放入Model"的困惑):业务流程放入Controller中,而业务流程中的具体业务规则放入Model中(这是符合SOA构的思想的---好大的帽子吧,能够阅读上面提到的代振军的那篇博文)。基于这个原则,不论是哪个登陆方法,其调度控制的业务流程都应该是这样:
    1. 接收客户端发出的身份信息(经过调度实现):Oxite示例的作法是经过调度,而MVCStore是直接在Action中Request.Form获取,缺点在于会让Action中的代码增加过快
    2. 判断此身份是否合法(经过调度实现):MVCStore中体现的很明显,在Model中建立有对应AuthenticationController的AuthenticationService,经过对此Service的调用来完成此业务流程步骤,而具体的业务规则就放在了Model中(根据此原则可将Model划分为两部分:一是数据模型实体部分,二是业务逻辑部分,以下图所示)
    3. 若是身份合法则承认(这是控制):"若是合法"是业务流程,而"承认"的具体内容(主要指的是对登陆身份的保持)则是业务规则,承认后固然就是控制输出视图了(这部分代码我也把它并入到业务流程中)
    4. 若是不合法则不承认(这也是控制):"若是不合法"是业务流程,而"不承认"通常不包含什么业务规则,直接开始控制视图输出

对于Controller在实际项目中须要当心时刻留心要始终保持Controller与View的轻快,当心随着业务复杂度提升而产生的困惑:有不少代码你不知道把它放哪,就只好把它放到控制层,最后发如今控制层中塞了太多的代码。有个叫Irwin的人提出了MOVE模式(这里有个简单的翻译版本)做为MVC模式的改进,其出发点也基于此,在这个MOVE模式中MOV从概念定义能够判断出就是对应了MVC(Operations对应着Controller),增长的一个Events彷佛是用来使视图和模型直接关联,我猜测做者多是在开发Controller时不少的Action须要根据复杂业务逻辑对视图产生影响,于是写了不少此类的代码在Controller中,当心的对Controller和View进行结构化组织,就可在很大程度上避免这种状况。

接下来针对我手上的系统的重构作些实际的思考来应用以上这些原则。

相关文章
相关标签/搜索