`
aben328
  • 浏览: 1459387 次
  • 性别: Icon_minigender_1
  • 来自: 广东
社区版块
存档分类

Java DTO(DataTransferObject)

    博客分类:
  • java
阅读更多

 

<!-- [if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:PunctuationKerning/> <w:DrawingGridVerticalSpacing>7.8 磅</w:DrawingGridVerticalSpacing> <w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery> <w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery> <w:ValidateAgainstSchemas/> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:Compatibility> <w:SpaceForUL/> <w:BalanceSingleByteDoubleByteWidth/> <w:DoNotLeaveBackslashAlone/> <w:ULTrailSpace/> <w:DoNotExpandShiftReturn/> <w:AdjustLineHeightInTable/> <w:BreakWrappedTables/> <w:SnapToGridInCell/> <w:WrapTextWithPunct/> <w:UseAsianBreakRules/> <w:DontGrowAutofit/> <w:UseFELayout/> </w:Compatibility> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> </w:WordDocument> </xml><![endif]--><!-- [if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" LatentStyleCount="156"> </w:LatentStyles> </xml><![endif]-->

<!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"\@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-font-kerning:1.0pt;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:595.3pt 841.9pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:42.55pt; mso-footer-margin:49.6pt; mso-paper-source:0; layout-grid:15.6pt;} div.Section1 {page:Section1;} -->

<!-- [if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;} </style> <![endif]-->

DTO

 

  Data Transfer Object (数据传输对象)

  您正在设计一个分布式应用程序,为了满足单个客户端请求,您发现自己对一个远程接口发出了多个 调用,而这些调用所增加的响应时间超出了可接受的程度。

  问题

  如何保留过程调用接口的简单语义,而不受远程通信固有的滞后时间问题的影响?

  影响因素

  在与远程对象通信时,请考虑下列需要权衡的因素:

  远程调用(那些必须跨越网络的调用)速度缓慢。虽然许多远程调用框架可以隐藏进行远程调用的复 杂性,但是它们不能消除发生通信所需的步骤。例如,必须先找到远程对象位置,而且建立与远程计算机的连接,然后才能将数据串行化为字节流,然后可能进行加 密,最后才能将其传输到远程计算机。

  在考虑网络性能时,必须同时考虑滞后时间和吞吐量。简单地说," 滞后时间" 描述了数据的首字节 到达目的地之前所经过的时间。" 吞吐量" 描述了在某个时间段(例如 1 秒)内通过网络发送的数据字节数。在基于 IP 路由的现代网络(例如 Internet )中,滞后时间可以是比吞吐量更大的因素。这意味着,传输 10 字节数据所用的时间可能几乎等于传输 1,000 字节数据所用的时间。在使用无连接协议(如 HTTP )时,此效果尤其明显。通常,网络速度越快可以使吞吐量得以增加,但是,要减少滞后时间则会更加困难。

  在设计对象接口时,好的做法是将大量信息隐藏在对象内,并提供一组细粒度方法来访问和操作该信 息。" 细粒度" 意味着每个方法都应该负责单个的、相当小的和基本的功能单位。此方法简化了编程,并提供了对对象内部的更佳抽象,从而增加了重用的可能性。 必须根据以下事实对此进行平衡取舍:使用较细粒度的方法意味着需要调用更多的方法才能执行高级别的任务。通常,在同一进程内调用方法时,这些额外函数调用 的开销是可接受的;但是,在跨进程和网络边界调用这些方法时,开销可能变得难以接受。

  避免远程调用中固有的滞后时间问题的最佳方法是进行更少的调用,并让每个调用传递更多的数据。 做到这一点的一种方法是,使用长参数列表来声明远程方法。这样,客户端就可以在单个调用中将更多的信息传递给远程组件。但是,这样做会使针对此接口的编程 容易出错,因为程序很可能仅按调用语句中的位置来调用外部方法的参数。例如,如果远程方法接受 10 个字符串参数,则开发人员很容易按错误顺序传递参数。编译器将无法检测到这样的错误。

  长参数列表无助于从远程调用向客户端返回更多的信息,因为大多数的编程语言将方法调用的返回类 型限制为单个参数。而巧合的是,在传输大多数数据时通常需要返回较多信息。例如,许多用户接口传输少量的信息,却希望返回大量结果数据。

  解决方案

  创建一个数据传输对象 (DTO) ,用该对象包含远程调用所需要的所有数据。修改远程方法签名,以便将 DTO 作为单个参数接受,并将单个 DTO 参数返回给客户端。在调用方应用程序收到 DTO 并将其作为本地对象存储之后,应用程序可以分别对 DTO 发出一系列单独的过程调用,而不会引发远程调用开销。Martin Fowler Patterns of Enterprise Application Architecture [Fowler03] 中对此模式进行了说明。

  下图显示客户端应用程序如何进行一系列远程调用以检索客户名称的各个元素。

  图 1: 没有 DTO 的远程调用

  DTO 允许远程对象在单个远程调用中将整个客户名称返回给客户端。在此示例中,这样做将使调用次数从 4 次减为 1 次。客户端进行单个调用,然后在本地与 DTO 交互,而不用进行多次远程调用(见图 2 )。

  图 2: 通过使用 DTO 减少调用次数

  DTO 是一组需要跨进程或网络边界传输的聚合数据的简单容器。它不应该包含业务逻辑,并将其行为限制为诸如内部一致性检查和基本验证之类的活动。注意,不要因实 现这些方法而导致 DTO 依赖于任何新类。

  在设计数据传输对象时,您有两种主要选择:使用一般集合;或使用显式的 getter setter 方法创建自定义对象。

  一般集合的优点是,只需要一个类,就可以在整个应用程序中满足任何数据传输目的。此外,集合类 (例如,简单数组或散列图)内置于几乎所有语言库中,因此您根本不必编写新类的代码。对 DTO 使用集合对象的主要缺点是,客户端必须按位置序号(在简单数组的情况下)或元素名称(在键控集合的情况下)访问集合内的字段。此外,集合存储的是同一类型 (通常是最一般的 Object 类型)的项目,这可以导致在编译时无法检测到的微妙但致命的编码错误。

  如果为每个 DTO 创建自定义类,则可以提供与任何其他对象完全一样的、客户端应用程序可访问的强类型对象,这样的对象可以提供编译时检查,并支持代码编辑器功能(如 Microsoft&reg; IntelliSense&reg; 技术)。主要缺点是,如果应用程序发出许多远程调用,则您最终可能必须编写大量类的代码。

  许多方法试图将这两种方法的优点结合在一起。第一种方法是代码生成技术,该技术可以生成脱离现 有元数据(如可扩展标记语言 (XML) 架构)的自定义 DTO 类的源代码。第二种方法是提供更强大的集合,尽管它是一般的集合,但它将关系和数据类型信息与原始数据存储在一起。Microsoft ADO.NET DataSet 支持这两种方法(请参阅在 .NET 中使用 DataSet 实现 Data Transfer Object )。

  有了 DTO 类以后,需要用数据填充它。大多数情况下,DTO 内的数据来自多个域对象。因为 DTO 没有行为,因此它不能从域对象提取数据。这是对的,因为如果让 DTO 不知道域对象,您就可以在不同的上下文中重用 DTO 。同样,您不希望域对象知道 DTO ,因为这可能意味着更改 DTO 将要求更改域逻辑中的代码,这将导致大量维护任务。

  最佳的解决方案是使用 Assembler 模式 [Fowler03] ,该模式可以用业务对象创建 DTO 或者相反。Assembler Mapper 模式的专门实例,在 Patterns of Enterprise Application Architecture [Fowler03] 中也提到过它。

  图 3: 使用 Assembler 将数据加载到 DTO

  Assembler 的关键特征是 DTO 和域对象不相互依赖。这就消除了这两种对象的相互影响。不利方面是 Assembler 同时依赖于 DTO 和域对象。对这些类的任何更改都可能导致必须更改 Assembler 类。

  示例

  请参阅在 .NET 中使用 DataSet 实现 Data Transfer Object

  测试考虑事项

  DTO 是简单对象,它不应该包含需要测试的任何业务逻辑。但是,您确实需要测试每个 DTO 的数据聚合。每个 DTO 可能需要测试,也可能不需要,这取决于您的序列化机制。如果序列化是框架的一部分,则只需要测试一个 DTO 。如果不是这样,请使用一般的反射机制,这样就不需要测试每个 DTO 的序列化。

  DTO 还对远程函数的可测试性有好处。通过使远程方法的结果能够在对象实例中使用,可以轻松地将此数据传递到测试模块,或将其与所需结果进行比较。

  安全考虑事项

  理想情况下,应该先筛选和验证从不可靠的来源获得的数据(如来自 Web 页的用户输入),然后将其置于 DTO 中。通过这样做,就可以认为 DTO 中的数据是相对安全的,从而简化了将来与 DTO 的交互。

  接收 DTO 的进程和关联用户的安全凭据也是值得注意的。DTO 通常包含从许多不同来源聚集在一起的大量信息。您是否已授权 DTO 的所有用户访问 DTO 所包含的所有信息?确保用户已得到授权的最佳方法是仅使用用户安全凭据所允许的特定数据填充 DTO 。努力避免让 DTO 负责自己的安全性。这将增加 DTO 对其他类的依赖数,这意味着必须将这些类部署到使用 DTO 的所有节点。这还会将安全性功能分散到更多类中,从而增大了安全风险,并对灵活性和可维护性产生负面影响。

  结果上下文

  Data Transfer Object 具有下列优缺点:

  优点

  减少了远程调用次数。通过在单个远程调用中传输更多的数据,应用程序可以减少远程调用次数。

  提高了性能。远程调用可以使应用程序的运行速度大大降低。减少调用次数是提高性能的最佳方法之 一。在大多数方案中,传输大量数据的远程调用所用的时间与仅传输少量数据的调用所用的时间几乎相等。

  隐藏内部情况。在单个调用中来回传递更多的数据,还可以更有效地将远程应用程序的内部情况隐藏 在粗粒度接口的背后。这就是使用 Remote Facade 模式 [Fowler03] 的主要原因。

  发现业务对象。在一些情况下,定义 DTO 有助于发现有意义的业务对象。在创建用作 DTO 的自定义类时,您通常会注意到作为一组凝聚性信息而显示给用户或另一个系统的元素分组。通常,这些分组用作描述应用程序所处理的业务域的对象的有用原型。

  可测试性。将所有参数封装到可序列化对象中可以提高可测试性。例如,可以从 XML 文件中读取 DTO ,并调用远程函数以测试它们。同样,可以轻松地将结果再序列化为 XML 格式,并将 XML 文档与所需结果进行比较,而不必创建冗长的比较脚本。

  缺点

  可能需要太多的类。如果选择了使用强类型的 DTO ,则可能必须为每个远程方法创建一个(如果考虑返回值,则为两个)DTO 。即使在粗粒度接口中,这也可能导致大量的类。编写如此数量的类的代码并管 理这些类会是很困难的。使用自动代码生成可以在一定程度上缓解此问题。

  增加计算量。如果将服务器上的一种数据格式转换为可以跨网络传输的字节流,并在客户端应用程序 内转换回对象格式,可以带来相当大的开销。通常,需要将来自多个源的数据聚合到服务器上的单个 DTO 中。要提高通过网络进行远程调用的效率,必须在任一端执行其他计算,才能聚合和串行化信息。

  增加编码工作量。可以用一行代码完成将参数传递到方法的操作。使用 DTO 要求实例化新对象,并为每个参数调用 setters getters 。编写此代码可能是很乏味的。

  参考资料:http://hi.baidu.com/linyang0106/blog /item/6229d6ce7c16ab0393457ea5.html

 

分享到:
评论

相关推荐

    java DTO 详解

    ### Java DTO 详解 #### 一、什么是DTO 在分布式系统的设计中,DTO(Data Transfer Object,数据传输对象)是一种非常重要的概念和技术手段。当客户端需要与服务器端进行交互时,尤其是在涉及大量的数据交换场景下...

    快速生成DTO

    在Java中,DTO通常是一个简单的POJO(Plain Old Java Object),包含属性、getter和setter方法。 4. **工具使用**: "buildDTO"可能是生成DTO的命令或者工具名称,它可能包含了解析Excel模板并自动生成Java代码的...

    java 使用 JAXB 将xml转换为 bean 包含xml和dto和读取文件的util类

    总结来说,这个压缩包提供的内容涉及了Java中使用JAXB进行XML与Java对象之间转换的实际应用,以及辅助的DTO和文件读取工具。这些对于理解和实现XML数据处理的Java应用非常有帮助。开发者可以通过学习和使用这些示例...

    POBOVODTOPOJODAO.zip_dto_java dto dao_java vo_qovod

    PO可以严格对应数据库表,一张表对映一个PO。... VO:value object值对象、view object视图对象 PO:持久对象 QO:查询对象 DAO:数据访问对象——同时还有DAO模式 DTO:数据传输对象——同时还有DTO模式

    java_dao_dto生成器

    Java DAO(Data Access Object)是一种...总的来说,"java_dao_dto生成器" 是一个强大的开发辅助工具,它能够加速Java应用的DAO层和DTO层的构建,使开发者能更高效地管理数据库访问代码,从而专注于业务逻辑的实现。

    数据库表转实体类和DTO

    数据库表转实体类和DTO是软件开发中一个常见的任务,特别是在Java后端开发中,它涉及到数据模型的设计和数据访问层的操作。实体类(Entity Class)通常代表数据库中的表,而DTO(Data Transfer Object)则用于在不同...

    Dto转实体类 AutoMapper

    在软件开发中,数据传输对象(Dto,Data Transfer Object)和实体类(Entity Class)是两种常见的对象模型,它们在不同的场景中各自扮演着重要的角色。Dto主要用于在系统组件之间传递数据,而实体类通常代表数据库中...

    Java利用Freemarker模板自动生成dto、dao、rowmapper、bo、service代码

    在生成DTO时,通常会从数据库表结构中获取字段信息,创建对应的Java类,这些类通常包含getter和setter方法,便于数据的封装和解封。 3. **DAO(Data Access Object)**: DAO是数据库操作的抽象层,用于隔离业务...

    导入Excel快速生成DTO

    在IT行业中,尤其是在Java开发领域,数据传输对象(DTO,Data Transfer Object)是一种常见的设计模式,用于在系统组件之间传递数据。"导入Excel快速生成DTO"这个标题暗示了一个工具或库,它能帮助开发者从Excel文件...

    Any2Dto插件,可以根据数据库和JavaCode生成强类型且精确字段的DTO

    这个插件专为IntelliJ IDEA用户设计,能够根据数据库结构和已有的Java代码自动生成强类型的DTO类,从而提高开发效率和代码质量。 首先,让我们深入了解DTO的概念。DTO是一种设计模式,主要用于隔离数据的表示层和...

    java Pojo转Map

    在Java编程中,Pojo(Plain Old Java Object)是一种简单的对象模型,通常用于表示数据实体。Map接口则是Java集合框架的一部分,它提供了键值对的数据存储方式,方便数据的存取。将Pojo对象转换为Map,可以简化数据...

    eclipse插件,根据数据库表自动生成DTO(pojo)插件

    在Java开发中,数据传输对象(DTO)和持久化对象(POJO)是常见的概念,它们用于在不同层之间传递数据。手动创建这些类可能会耗费大量时间,特别是在处理大量数据库表时。因此,"eclipse插件,根据数据库表自动生成...

    DTO注解校验部分展示

    如果感觉有帮助请点赞,本文件用于springboot+mybaties;如果感觉没有用处请找其他。注意在使用校验注解时,一定要和@valid一起使用,否则校验不会起效。

    Betfair-APING-DTO-codeGen:Scrapper 从 Confluence 文档中为 Betfair APING 生成 Java DTO

    【标题】"Betfair-APING-DTO-codeGen:Scrapper 从 Confluence 文档中为 Betfair APING 生成 Java DTO" 提供了一个工具,它自动化了从 Confluence 文档中提取数据并生成适用于 Betfair API 的 Java 数据传输对象(DTO...

    Java中 PO VO BO DTO DAO 和 POJO 关系图

    Java中 PO VO BO DTO DAO 和 POJO 关系图

    分页dto把html写在dto里

    在IT行业中,DTO(Data Transfer Object)是一种设计模式,用于在系统之间传递数据,它将业务逻辑层与表现层的数据解耦。标题“分页dto把html写在dto里”和描述“把分页按钮写在dto里,其他dto继承他”表明了一个...

    kingdao自动生成DAO/DTO

    modify the property file of the database path, driver, user name, password, enter CMD to the D drive is running java-jar kingdao.jar disk in D test folder under the root directory of DAO and DTO ...

    使用Java 8 Lambda表达式将实体映射到DTO的操作

    使用Java 8 Lambda表达式将实体映射到DTO的操作 在Java 8中,Lambda表达式是映射实体到DTO的一种非常有效的方法。通过使用 Lambda 表达式,我们可以将实体映射到DTO,以便更方便地进行数据处理和展示。在本文中,...

    Java源码常见字母的大小写转换

    在Java编程语言中,字符的大小写转换是常见的操作,特别是在处理字符串时。Java提供了多种方法来实现这一功能,使得开发者能够轻松地在大写和小写字母之间切换。以下是一些关键的知识点: 1. **`Character` 类:** ...

Global site tag (gtag.js) - Google Analytics