使用View Model从表现层分离领域模型
本文来自: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种方法:
- 把领域模型当作视图模型来用,也就是领域模型就是视图模型,大部分都是这么用的。
- 视图模型里面包含一个领域模型,定义一个视图模型,里面包含了一个领域模型,通过属性方式进行访问。
- 将领域模型映射到视图模型,领域模型并没有直接映射到视图模型,需要处理这种映射关系。
我们不建议直接把领域模型实体暴露给视图,因为有许多细微之处,可能导致您混合业务和表示层的逻辑,无论是领域实体的属性显示还是业务的验证规则,这都是应用程序处理的不同方面。直接将你的领域模型作为Conroller上的处理参数面临着安全风险,因为Controller或者Model binder必须确保属性验证和用户不能修改她自己不能修改的属性(例如,用户手动更新了一个隐藏的输入值,或增加一个额外的属性值,而这个并不是界面上的元素,但却正好领域模型实体的属性,这种风险叫做“over-posting”),即使对当前版本的领域模型做了正确的验证,领域模型将来可能做了变更修改,并没有出现编译错误或者警告,可能导致新的风险。
我们应当避免使用前两种方法将领域模型转换成视图模型,推荐使用第三种方法,定义单独的视图模型类。做这种领域模型到视图模型的转换工作是一种重复性的工作,已经有几个工具可以帮助你来完成这项工作。最常用的一个工具就是.NET 社区的开源项目AutoMapper。
如何使用AutoMapper可以参考下面的两篇文章介绍:
AutoMapper Formatters are Cool - ASP.NET MVC Style
使用View Model从表现层分离领域模型的更多相关文章
- 表现层的设计(一)——常用的模式、Json与DTO
上几篇博文介绍了 业务逻辑层和数据访问层,我认为写博文的作用主要是向业界的读者交流一种思想,点到为止,至于学习架构设计,通过几篇博文是讲不清楚的,还需要[基础]扎实的情况下,[反复]研究[权威]的书籍 ...
- 表现层的设计(二)——MVC如何处理复杂的界面元素
需求描述 一个比较复杂的页面,界面中包含的元素数据来自于许多个有关联或者无关联的表,然后我们要做的就是将数据呈现在界面上. 10年前大概都是这么干的 直接写一个复杂的SQL语句,返回一个包含所需数据的 ...
- 一个项目中说系统分为表现层、控制层、逻辑层、DAO层和最终数据库五层架构-转
表现层就是看到的东西,比如你现在看到的当前页面控制层就将你的请求从页面传到后台代码逻辑层就是处理你的请求的代码DAO层就是将数据存到数据库中的代码数据库就是数据库了,存东西用的 ,DAO层就是将访问数 ...
- 请问JAVA三层架构,持久层,业务层,表现层,都该怎么理解?和MVC三层模型有什么区别
持久层用来固化数据,如常说的DAO层,操作数据库将数据入库业务层用来实现整体的业务逻辑 如 前台获得了数据,逻辑层去解析这些数据,效验这些数据等操作表现层很好解释 你现在看到的网页 一些界面 都属于 ...
- 表现层技术以及Freemaker使用教程
表现出计数以及Freemaker详解 在java领域,表现层技术主要有三种:jsp.freemarker.velocity.jsp是大家最熟悉的技术优点: 1.功能强大,可以写java代码 2.支持j ...
- 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) ...
- 应用程序框架实战三十三:表现层及ASP.NET MVC介绍(二)
最近的更新速度越来越慢,主要是项目上比较忙,封装EasyUi也要花很多时间.不过大家请放心,本系列不会半途夭折,并且代码干货也会持续更新.本文继续介绍表现层和Asp.net Mvc,我将在本篇讨论一些 ...
- 应用程序框架实战三十:表现层及ASP.NET MVC介绍(一)
本文将介绍表现层及ASP.NET MVC的一些要点,特别是ASP.NET MVC的一些抽象和封装技巧,如果你对MVC还不了解,可以参考<ASP.NET MVC4 高级编程>,作者Jon G ...
- MyBatis知多少(6)表现层与业务逻辑层
表现层 表现层负责向最终用户展示应用程序的控制方式以及数据.它还要负责所有信息的布局和格式.今天,商业应用程序最流行的表现方式应该算是Web前端了,它使用HTML和JavaScript并通 过Web浏 ...
随机推荐
- FZU1862(线段树 或者 DP)
Problem 1862 QueryProblem Accept: 100 Submit: 249Time Limit: 2000 mSec Memory Limit : 32768 KB ...
- hdu2208之搜索
唉,可爱的小朋友 Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- IOS 计算密码强度
+ (BOOL) judgeRange:(NSArray*)conditionArr Password:(NSString*)password { NSRange range; BOOL result ...
- iOS 无效的版本,提交成功,不出现版本号
最近更新到 iOS 10,提交审核 会卡在 转菊花 ...需要更新到Xcode 8 去提交. 然后提交成功后,版本管理 新版本,构建版本 迟迟不出来.恭喜你,你的版本是无效的.请看看 你的 公司app ...
- AliCTF 2016
上上周参加了阿里的CTF,靠着最后绝杀队伍有幸拿到了国内第一名,也顺利进入了XCTF Final.把自己做的几个题简单写了下,发出来也算个总结吧. PWN-FB 经典的null byte overfl ...
- Windows下安装Memcache
安装步骤的时候只需要做两步: 第一步:安装memcache.exe 服务. 第二步:安装php_memcache.dll扩展,让php支持memcache. 1.安装 memcache.exe 服务 ...
- Windows7中安装内存与可用内存不一致的解决办法
转载:http://blog.sina.com.cn/s/blog_56741a420100h9d1.html 问题现象: 安装完Windows7后,在计算机->属性中,会看到安装内存.但有时在 ...
- React-Native post和get请求
post: fetchData (title) { fetch(REQUEST_URL, { method: 'POST', headers: { 'Accept': 'application/jso ...
- Spring 注入数据源
一.在项目中添加dataSource所用到的包 dbcp数据源所需包: commons-dbcp.jar commons-pool.jar C3P0数据源所需包: c3p0-0 ...
- java基础知识——程序员面试基础
一.面向对象的特征有哪些? 答:①.抽象:抽象是忽略一个主题中与当前目标无关的那些方面,一边更充分的注意与当前目标有关的方面.抽象并不打算了解全面问题,而是选择其中的一部分,暂时不用部分细节.抽象包括 ...