[PoEAA] Learning Notes of Data Transfer Object

  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作为中间人:

[PoEAA] Learning Notes of Data Transfer Object

    上图来自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

 

你可能感兴趣的:(object)