本文来自:http://www.cnblogs.com/shanyou/archive/2010/04/03/1703501.html

Model-View-Controller(模型-视图-控制器,MVC) 模式将你的软件组织并分解成三个截然不同的角色:

  • Model 封装了你的应用数据、应用流程和业务逻辑。

  • View 从 Model 获取数据并格式化数据以进行显示。

  • Controller 控制程序流程,接收输入,并把它们传递给 Model 和 View。

与其它设计模式不同,MVC 模式并没有直接反映一个你能够编写或配置的类结构。相反,MVC 更像一个概念上的指导原则或范型。概念上的 MVC 模式被描述为三个对象 —— Model、View 和 Controller —— 之间的关系。由于 View 和 Controller 都可以从 Model 请求数据,所以 Controller 和 View 都依赖 Model。任何输入都通过 Controller 进入你的系统,然后 Controller 选择一个 View 来发出结果。

Model 包含了你的应用逻辑和数据,在你的应用程序中,它很可能是主要的值驱动器。Model 没有任何与表现层相关的特性,而且也和 HTTP 请求处理职责中完全无关。

Domain Model 是一个对象层,是对现实世界逻辑、数据和你应用程序所处理的问题的抽象。Domain Model 可分为两大类:Simple Domain Model 和 Rich Domain Model。

Simple Domain Model 往往是业务对象和数据库表之间一对一的通信。你已经见过的几种模式 —— Active Record、Table Data Gateway,以及 Data Mapper,所有这些与数据库相关的设计模式 —— 可以帮助你把与数据库相关的逻辑组织成一个 Domain Model。

Rich Domain Model 包含复杂的,使用继承机制紧密联系在一起的对象网络,在本书和 GoF 一书中介绍的众多模式起着杠杆作用。Rich Domain Models 往往是柔性的,精心测试过的,不断重构的,而且与它们所表达的领域所需的业务逻辑紧密耦合。

采用哪种 Domain Model 类型取决于你的应用环境。如果你正在建立的是一个非常简单的表单处理 web 应用,没必要建立 Rich Domain Model。然而,如果你正在编写一个价值数百万的企业内联网架构的核心库,那么努力开发一个 Rich Domain Model 就是值得的,它可以为你提供一个准确表达业务过程的平台,并可以让你快速传输数据。

Martin Fowler 在 PoEAA 中同时简要介绍了两种 Domain Model。而 Eric Evans 的 Domain Driven Design 一书,则完全专注于 Rich Domain Model 的实践应用和开发过程。

View 用于处理所有表现层方面的问题。View 从 Model 获取数据,并可以把它格式化成用于 web 页的 HTML,用于 web 服务的 XML,或用于 email 的文本。

许多的MVC模式的实现也都使用一个View Model或Application Model的概念,Controller是沟通的媒介,架起领域模型和用户界面之间的桥梁,属于表现层。为了View的简单性,Controller负责处理或者将领域模型转换成一个View Model,这通常叫做数据传输对象(DTO)。

<译>12个asp.net MVC最佳实践针对Model的最佳实践有这么一段:

7–DomainModel != ViewModel

 DomainModel代表着相应的域,但ViewModel却是为View的需要而创建。这两者之间或许(一般情况下都)是不同的,此外DomainModel是数据加上行为的组合体,是由复杂的变量类型组成的并且具有层次。而ViewModel只是由一些String等简单变量类型组成。如果想移除冗余并且容易导致出错的ORM代码,可以使用AutoMapper.如果想要了解更多,我推荐阅读:ASP.NET MVC View Model Patterns.

那么领域模型(Domain Model )和视图模型(View Model)有什么不同呢?

在ASP.NET MVC的应用程序中经常可以可以看到View Model,经常我们都认为领域模型和视图模型是同一个东西。这特别是把领域模型包含在数据传输对象DTO里的时候,例如使用Entity Framework之类的ORM工具生成的实体。在这种情况下,领域模型和视图模型包含的实体非常相似,都是一些简单的CRUD操作。

这些实体有许多属性,有相同或类似的名称,你可以很容易地映射领域实体对应视图模型中的一个属性。不过,这些相似的属性也可能略有不同,例如类型或者格式。例如,用户填写的用户界面的一个属性,他在视图模型里可能是一个“Nullable”的。另一方面,领域实体可能需要一个经过验证的合法的值,所以需要一个在用户界面的领域模型之间的转换。另一个例子是,用户界面可能会显示一个滑块,用于用户选择多少天以后提交他的订单。在这种情况下,视图模型可能使用一个整数属性来表示,领域模型通常是一个日期值。

视图模型通常只包含领域模型的一个子集,而且只包含界面上所需要的属性。此外,视图模型可能是一个领域模型树的扁平版本,例如,一个Customer实体有一个Address,而这又是一个整体,它包含街道地址,邮政编码,国家等。一个Customer 视图模型用于显示数据,将地址数据拉平填充到视图模型类里。

此外如果一个View需要同时处理几个领域模型,View Model就是这几个Domain Model的总和。领域模型和视图模型之间有很多相似的地方,我们经常干脆就把Domain Model当作View Model来使用了。

上面讨论了领域模型和视图模型的相似性,我们来看看都有几种方式把领域模型转换为视图模型,通常有3种方法:

  1. 把领域模型当作视图模型来用,也就是领域模型就是视图模型,大部分都是这么用的。
  2. 视图模型里面包含一个领域模型,定义一个视图模型,里面包含了一个领域模型,通过属性方式进行访问。
  3. 将领域模型映射到视图模型,领域模型并没有直接映射到视图模型,需要处理这种映射关系。

我们不建议直接把领域模型实体暴露给视图,因为有许多细微之处,可能导致您混合业务和表示层的逻辑,无论是领域实体的属性显示还是业务的验证规则,这都是应用程序处理的不同方面。直接将你的领域模型作为Conroller上的处理参数面临着安全风险,因为Controller或者Model binder必须确保属性验证和用户不能修改她自己不能修改的属性(例如,用户手动更新了一个隐藏的输入值,或增加一个额外的属性值,而这个并不是界面上的元素,但却正好领域模型实体的属性,这种风险叫做“over-posting”),即使对当前版本的领域模型做了正确的验证,领域模型将来可能做了变更修改,并没有出现编译错误或者警告,可能导致新的风险。

我们应当避免使用前两种方法将领域模型转换成视图模型,推荐使用第三种方法,定义单独的视图模型类。做这种领域模型到视图模型的转换工作是一种重复性的工作,已经有几个工具可以帮助你来完成这项工作。最常用的一个工具就是.NET 社区的开源项目AutoMapper

如何使用AutoMapper可以参考下面的两篇文章介绍:

AutoMapper Formatters are Cool - ASP.NET MVC Style

AutoMapper in NerdDinner

使用View Model从表现层分离领域模型的更多相关文章

  1. 表现层的设计(一)——常用的模式、Json与DTO

    上几篇博文介绍了 业务逻辑层和数据访问层,我认为写博文的作用主要是向业界的读者交流一种思想,点到为止,至于学习架构设计,通过几篇博文是讲不清楚的,还需要[基础]扎实的情况下,[反复]研究[权威]的书籍 ...

  2. 表现层的设计(二)——MVC如何处理复杂的界面元素

    需求描述 一个比较复杂的页面,界面中包含的元素数据来自于许多个有关联或者无关联的表,然后我们要做的就是将数据呈现在界面上. 10年前大概都是这么干的 直接写一个复杂的SQL语句,返回一个包含所需数据的 ...

  3. 一个项目中说系统分为表现层、控制层、逻辑层、DAO层和最终数据库五层架构-转

    表现层就是看到的东西,比如你现在看到的当前页面控制层就将你的请求从页面传到后台代码逻辑层就是处理你的请求的代码DAO层就是将数据存到数据库中的代码数据库就是数据库了,存东西用的 ,DAO层就是将访问数 ...

  4. 请问JAVA三层架构,持久层,业务层,表现层,都该怎么理解?和MVC三层模型有什么区别

    持久层用来固化数据,如常说的DAO层,操作数据库将数据入库业务层用来实现整体的业务逻辑 如 前台获得了数据,逻辑层去解析这些数据,效验这些数据等操作表现层很好解释  你现在看到的网页 一些界面 都属于 ...

  5. 表现层技术以及Freemaker使用教程

    表现出计数以及Freemaker详解 在java领域,表现层技术主要有三种:jsp.freemarker.velocity.jsp是大家最熟悉的技术优点: 1.功能强大,可以写java代码 2.支持j ...

  6. CGI servlet Applet Scriptlet Scriptlet JSP data layer(数据层),business layer(业务层), presentation layer(表现层)

    https://en.wikipedia.org/wiki/Common_Gateway_Interface In computing, Common Gateway Interface (CGI) ...

  7. 应用程序框架实战三十三:表现层及ASP.NET MVC介绍(二)

    最近的更新速度越来越慢,主要是项目上比较忙,封装EasyUi也要花很多时间.不过大家请放心,本系列不会半途夭折,并且代码干货也会持续更新.本文继续介绍表现层和Asp.net Mvc,我将在本篇讨论一些 ...

  8. 应用程序框架实战三十:表现层及ASP.NET MVC介绍(一)

    本文将介绍表现层及ASP.NET MVC的一些要点,特别是ASP.NET MVC的一些抽象和封装技巧,如果你对MVC还不了解,可以参考<ASP.NET MVC4 高级编程>,作者Jon G ...

  9. MyBatis知多少(6)表现层与业务逻辑层

    表现层 表现层负责向最终用户展示应用程序的控制方式以及数据.它还要负责所有信息的布局和格式.今天,商业应用程序最流行的表现方式应该算是Web前端了,它使用HTML和JavaScript并通 过Web浏 ...

随机推荐

  1. poj 1001 求高精度幂

    本题的测试用例十分刁钻,必须要考虑到很多的细节问题,在这里给出一组测试用例及运行结果: 95.123 12 548815620517731830194541.899025343415715973535 ...

  2. Course Schedule 解答

    Question There are a total of n courses you have to take, labeled from 0 to n - 1. Some courses may ...

  3. Light OJ 1067 Combinations (乘法逆元)

    Description Given n different objects, you want to take k of them. How many ways to can do it? For e ...

  4. java提高篇(二二)-----LinkedList

    摘自http://blog.csdn.net/chenssy/article/details/18099417  java提高篇(二二)-----LinkedList 一.概述 LinkedList与 ...

  5. unix系统非roo账号安装JDK

    AIX系统用户rusky(非root用户,没有权限修改/etc/profile和/etc/environment文件 )直接解压JDK.zip文件,解压后把JAVA目录拷贝到/home/rusky目录 ...

  6. [Manacher][HDU3613][Best Reward]

    题意: 将一段字符串 分割成两个串 如果分割后的串为回文串,则该串的价值为所有字符的权值之和(字符的权值可能为负数),否则为0. 问如何分割,使得两个串权值之和最大 思路: 裸的: 枚举分割点,计算, ...

  7. 使用react-native做一个简单的应用-03欢迎界面

    Android和iOS的欢迎界面是不一样的,在iOS中有一个默认的欢迎界面,而Android则需要自己写.因此我就分开说一下这两个平台的欢迎界面的搭建.下面先看一下实现效果: Android: iOS ...

  8. frame和iframe

    1.frame不能脱离frameSet单独使用,iframe可以: 2.frame不能放在body中:如下可以正常显示: <!--<body>--> <frameset ...

  9. jsp基础之 jstl

    JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能. JSTL支持通用的.结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签,SQL标签. 除了这些,它还提供 ...

  10. 从汇编看c++的虚拟继承以及其内存布局(一)

    先看第一种最简单的情形,所有类中没有任何虚函数的菱形继承. 下面是c++源码: class Top {//虚基类 public: int i; Top(int ii) { i = ii; } }; c ...