第一章 设计程序架构 之 分层架构

1. 概述

  本章主要介绍 程序分层架构的主要组成部分,比如 数据访问方式 以及 Soc(separation of concern).其中重要的组成部分之一就是MVC架构。本章还将介绍MVC架构的各个组成部分。

2. 主要内容

  2.1 数据访问

    2.1.1 两种主要的数据访问方式:

      ① object relational mapper(O/RM):对象关系映射,是把关系型的数据库信息映射成对象。支持MVC4的O/RM产品包括:Nhibernate、The       Entity Framework、Linq to Sql。

      ② 实现自己的数据交互组件:自己实现数据和对象的映射操作,用于数据模型和对象模型差异较大的情况以及非关系型数据库的情况。

    2.1.2 确定了数据访问方式以后,下面就需要考虑实现方式了:

                ① 自定义交互方式的,需要自己实现各个部分,比如非空验证。

      ② Linq to sql ,与已经存在的数据库交互,不支持根据模型创建数据库。

      ③ Entity Framework 和 NHibernate 都支持根据模型生成数据库。

    2.1.3 仓库模型(Repository Pattern)

      C#中使用较多的数据访问模型是 仓库模型。

      实现原理是在 业务逻辑层 和 数据访问层 增加一个抽象层,用于处理业务逻辑和数据访问层的交互和变化,从而将两层解耦。

      *仓库模型 对于 单元测试 也很有用。

      

  2.2 关注点分离(separation of concern(Soc))

    Soc是一种软件开发方式,核心思想是 将一个计算机程序分解成多个不同的部分,每一个部分都有独立的目标,可以进行独立的开发和更新。

    分层架构就是使用Soc思想的典型案例。

  2.3 如何恰当的使用 模型、视图 和 控制器

    如何恰当的使用 模型、视图 和 控制器,是实现设计良好的程序的关键因素。

    2.3.1 模型

      模型是程序中用于处理业务逻辑的部分。不同于MVC架构的其他部分,模型不实现任何的特殊接口,不继承特定的基类。

      模型类放在Models文件夹中,编译到独立的程序集中。可以方便的实现共享。

      ① 视图模型 描述 表现层的数据。表现层的任何数据都可以在视图模型的属性中找到。

      视图模型一般是多个类合成的一个对象。

      ② 输入模型  用于表示从客户端到服务端的http请求的数据信息。

      ③ 模型绑定 是将一个提交表单映射到一个类型,并且把这个类型作为一个参数传递到action方法。

      DefaultModelBinder 自动把提交信息映射到相匹配的模型的属性中。

      *通过实现IModelBinder,可以自定义模型绑定器。

    2.3.2 控制器

      控制器 用于处理传入的请求,处理用户输入和交互,执行程序逻辑。

      Controller基于ControllerBase类,负责定位相应的action方法去调用,验证action方法,获取模型中的值用作参数,管理所有的错误,调用视图引擎去生成页面信息。

      Action方法是典型的一对一映射用户交互的方式,每一次用户交互都创建调用一个唯一的资源定位符(URL). Routing引擎利用Routing规则来判断Controller 和 Action方法 哪个需要被调用。

      区别于传统的Asp.Net方式,控制器是进行功能性划分的一种方式。可以用一个控制器来处理多个页面的信息。是根据功能而不是具体的页面来划分的。

      规划控制器架构的最佳时机是在创建数据模型的时候。一般情况下如果界面与数据模型不能很好的映射,那么控制器应该也不能很好的与数据模型匹配。这个时候应该考虑用一个独立的业务逻辑层来适配之。

      Routing表保存在Global.asax文件中,用于定义映射规则,解析请求url信息,映射到相应的controller和action上。

      Controller Actions 还可以使用一些attributes来向framework提供一些额外信息。使用最多的包括:ActionName、AcceptVerbs、NonAction.

      异步控制器是在MVC4中新加入的。用于取代MVC3中的AsyncController。

public async Task<ActionResult> List() 
{ 
    ViewBag.SyncOrAsync = "Asynchronous";  
    string results = string.Empty;  
    using (HttpClient httpClient = new HttpClient() 
    { 
        var response = await httpClient.GetAsync(new Uri("http://externalfeedsite"));  
        Byte[] downloadedBytes = await response.Content.ReadAsByteArrayAsync(); 
        Encoding encoding = new ASCIIEncoding(); 
        results = encoding.GetString(downloadedBytes);  
    } 
    return PartialView("partialViewName", results);

    2.3.3 视图

      视图是负责向用户展示信息,与用户交互的部分。

      一组信息通过 ViewDataDictionary发送到视图层。可以通过标准的访问字典的方式访问这些信息。

      ① 强类型视图(Strongly-typed views): 附加一个模型,可以提供智能感知及自动代码生成。

      ② 特定视图模型(View-specific model):一个中间类,用于 当显示信息不能直接和领域模型匹配时。

        该模型从一个或多个模型对象中收集视图需要的数据,放到一个与视图匹配的特定的类中。

      ③ 部分视图(Partial View) : Asp.net MVCs 版本的用户控件,可以内嵌到某一个页面里。

      ④ 母版或布局页(Master or Layout page):用于在多个页面中共享一个设计。

      ⑤ 脚手架模板(Scaffold template): 一套CRUD操作的模板,vs可以根据模板自动生成相应的代码。默认是T4模板,也可自定义。

      * Razor视图引擎和Web Forms视图引擎

        Razor视图引擎 提供了一种流线型的、简洁的、有表现力的 流畅格式,可以大大减少视图中的代码量。

        Web Forms视图引擎 是初始的视图引擎,类似Asp.Net,使用  <% 标记。

      *扩展视图引擎

        Razor视图引擎和Web Forms视图引擎都从BuildManagerViewEngine派生,可以实现自己的HTML Helper类,在视图内生成Html信息。

  2.4 如何选择 在客户端处理 还是 在服务端处理

    客户端处理不用经过网络,相应速度和稳定性好,但是很难保证安全性。

    比较推荐的做法是两种方式都用,拿数据验证举例,客户端验证用户提交用户体验,服务端的验证用于保证数据的有效性。

  2.5 设计程序伸缩性

    两种主要的扩展伸缩方式为水平方式和垂直方式

    ① 水平方式:通过给系统添加新节点来实现。比如web farm。使用加载平衡器或者其他网络设备来决定要访问的系统节点。

      如果使用水平方式扩展,设计时需要考虑的地方包括:发布使用的网络硬件和session、cache及文件位置的处理。

    ② 垂直方式:通过给单个系统增加系统资源来实现。比如增加Cpu和内存。

      如果使用垂直方式扩展,设计时需要考虑的地方包括:多线程、I/O、垃圾回收器 以及 其他Cpu或内存相关的部分。

    *设计数据库时也要考虑伸缩性。

    *使用云服务可以有助于解决伸缩性问题。

3. 总结

  ① Asp.Net Mvc是一种典型的Soc架构,通过把程序划分为 模型、视图和控制器来分散职责。

  ② 视图是直接跟用户交互的一层。编码时,视图层不要直接修改模型层(要通过控制器)。

    MVC4中有两种视图引擎 Razor 和 Web Form。

  ③ 控制器用于处理Http请求、发送命令给模型层更新其状态、发送命令给相关的视图更新显示。

  ④ 模型用于处理数据和业务逻辑,还负责管理持久化层和数据访问。

  ⑤ 客户端处理还是服务端处理的建议,如果是相同的业务作用于多个视图,或者是涉及到大数据量传输的,建议放到服务端处理。

  ⑥ 设计程序时,伸缩性是首要需要考虑的部分。这个会影响到缓存、客户端还是服务端处理以及数据访问的设计实现。

  ⑦ 使用Entity Framework时,管理数据库创建有三种方式:数据库先行、代码先行 和 模型先行。

  ⑧ Asp.Net Mvc的无状态天性会导致EF的一些特性不能使用。这就要求开发者编写额外的代码来更好的使用DBContext类以及其对数据的访问操作。

    抽象化数据访问是比较好的一种方式,可以使用仓库模式来实现。

原文地址:https://www.cnblogs.com/stone_lv/p/4561559.html