惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

罗磊的独立博客
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
MyScale Blog
MyScale Blog
M
MIT News - Artificial intelligence
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
T
The Blog of Author Tim Ferriss
Martin Fowler
Martin Fowler
博客园 - 【当耐特】
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
宝玉的分享
宝玉的分享
Engineering at Meta
Engineering at Meta
WordPress大学
WordPress大学
Google DeepMind News
Google DeepMind News
C
Check Point Blog
Last Week in AI
Last Week in AI
F
Fortinet All Blogs
博客园 - 聂微东
Blog — PlanetScale
Blog — PlanetScale
H
Help Net Security
GbyAI
GbyAI
云风的 BLOG
云风的 BLOG

博客园 - 水言木

好久没来了,发个招聘贴 RavenDB Tips: 巧妙设计文档的Id格式以提升查询性能 CQRS实践(4): 领域事件 CQRS实践(3): Command执行结果的返回 CQRS实践(2): Command的实现 CQRS实践(1): 什么是CQRS 准备重新开始写点东西 不要让编写set访问器成为习惯 再谈“引用” 使用UrlRewriter进行Url重写的完整解决方案 迅速搭建SVN环境 小议GridView中的删除按钮 工厂的那些事儿 关于Ajax的只言片语[2008.7.31最后更新] 重温:从aspx到dll 小记一次让我误会的引用传参 关于ASP.NET的只言片语[2008.8.12最后更新] .ctor,.cctor 以及 对象的构造过程 汶川地震小感
[PoEAA] Learning Notes of Data Transfer Object
水言木 · 2008-08-21 · via 博客园 - 水言木

  Data Transfer Object,故名思义,就是用来传输数据的对象。

  在一个进程内,方法的调用是非常快的,但不同的进程间的调用却慢的多,尤其在分布式应用程序中,远程过程调用是非常耗时的,为了提高效率,我们就想到在每一次的调用中,尽可能传输多的数据(如果频繁调用,而每次调用都只传输很小的数据量,比如第一次调用为了取得一篇文章的作者姓名,第二次调用为了取得作者所在的城市,那开销是非常大的)。

  在MSDN中有文章提到:

     In modern IP routing-based networks (for example, the Internet), latency can be a bigger factor than throughput. That means it may take almost the same amount of time to transmit 10 bytes of data as it takes to transmit 1,000 bytes of data. This effect is particularly pronounced when using connectionless protocols such as HTTP. Faster networks can often increase the throughput(吞吐量), but latency(延迟) is much more difficult to reduce.

  从上也可以看出,即使我们每次调用时传输很少的数据量,效率也不会有多大提升。

  为了在一次调用中传输更多的数据,我们可以很自然的想到通过传递许多的参数,但是,想象一下,假如我们给远程过程传递了10个字符串参数,那很可能会出错的(比如在编程时把第二个和第三个参数写反了),而如果要返回多个参数,那更是不可能的。

  于是,Data Transfer Object (DTO) 出场了。它把前面讲到的方法参数都抽过来当作自己的值域,并对它们设置getter和setter,这就是DTO,它是一个简单的数据结构,没有程序逻辑,它的任务就是以比较方便的方式让远程调用时能一次传输更多的数据。比如前面的那个场景,就可以把文章的标题,作者姓名,作者所在城市都放在DTO中,然后分别设置getter和setter。

  DTO的值域要是很简单的类型,因为要保证客户端和服务器端都能轻松地认识它们,DTO更不该包含许多业务逻辑,它的目的就是用来在远程过程调用时传输数据的。

  DTO的值域一般都是从多个领域对象(Domain Object)中而来,比如前面的场景,那个DTO的值域就是从文章类和作者类中而来。

  DTO一般是为了专门的客户端用途而设计的,比如一个网页要显示的内容,一个GUI,同样,这会使得在远程调用很频繁却又不是都调用同样方法时,为了远程调用而设计大量的DTO,同时也要消耗体力去编写这些DTO(当然也可以用代码生成工具)

  我们不应该让领域对象依赖DTO,也不该在DTO中加入许多计算逻辑,所以,为了联系DTO和领域对象,往往会有一个Assembler作为中间人:

    上图来自MSDN

  但是这么一来,Assembler就过分依赖了DomainObject和DTO,Domain Object和DTO的改动都会影响到Assembler。

参考资料:

1. Martin Fowler : "Patterns of Enterprise Application Architecture";

2. MSDN : Data Transfer Object, http://msdn.microsoft.com/en-us/library/ms978717.aspx