美文网首页Java技术升华javajava基础或面试问题
Java中 VO、 PO、DO、DTO、 BO、 QO、DAO、

Java中 VO、 PO、DO、DTO、 BO、 QO、DAO、

作者: 聂叼叼 | 来源:发表于2018-06-07 10:25 被阅读232次

    一、概念

    1.PO(persistant object) 持久对象

    在 o/r 映射的时候出现的概念,如果没有 o/r 映射,没有这个概念存在了。通常对应数据模型 ( 数据库 ), 本身还有部分业务逻辑的处理。可以看成是与数据库中的表相映射的 java 对象。最简单的 PO 就是对应数据库中某个表中的一条记录,多个记录可以用 PO 的集合。 PO 中应该不包含任何对数据库的操作。

    2.DO(Domain Object)领域对象

    就是从现实世界中抽象出来的有形或无形的业务实体。一般和数据中的表结构对应。

    3.TO(Transfer Object) ,数据传输对象

    在应用程序不同 ( 关系 ) 之间传输的对象

    4.DTO(Data Transfer Object)数据传输对象

    这个概念来源于J2EE的设计模式,原来的目的是为了EJB的分布式应用提供粗粒度的数据实体,以减少分布式调用的次数,从而提高分布式调用的性能和降低网络负载,但在这里,我泛指用于展示层与服务层之间的数据传输对象。

    5.VO(view object) 值对象

    视图对象,用于展示层,它的作用是把某个指定页面(或组件)的所有数据封装起来。

    6.BO(business object) 业务对象

    从业务模型的角度看 , 见 UML 元件领域模型中的领域对象。封装业务逻辑的 java 对象 , 通过调用 DAO 方法 , 结合 PO,VO 进行业务操作。 business object: 业务对象 主要作用是把业务逻辑封装为一个对象。这个对象可以包括一个或多个其它的对象。 比如一个简历,有教育经历、工作经历、社会关系等等。 我们可以把教育经历对应一个 PO ,工作经历对应一个 PO ,社会关系对应一个 PO 。 建立一个对应简历的 BO 对象处理简历,每个 BO 包含这些 PO 。 这样处理业务逻辑时,我们就可以针对 BO 去处理。

    7.POJO(plain ordinary java object) 简单无规则 java 对象

    纯的传统意义的 java 对象。就是说在一些 Object/Relation Mapping 工具中,能够做到维护数据库表记录的 persisent object 完全是一个符合 Java Bean 规范的纯 Java 对象,没有增加别的属性和方法。我的理解就是最基本的 Java Bean ,只有属性字段及 setter 和 getter 方法!

    8.DAO(data access object) 数据访问对象

    是一个 sun 的一个标准 j2ee 设计模式, 这个模式中有个接口就是 DAO ,它负持久层的操作。为业务层提供接口。此对象用于访问数据库。通常和 PO 结合使用, DAO 中包含了各种数据库的操作方法。通过它的方法 , 结合 PO 对数据库进行相关的操作。夹在业务逻辑与数据库资源中间。配合 VO, 提供数据库的 CRUD 操作

    二、区别

    1、vo,dto,do在三层架构应用中的位置?

    
            用户发出请求(可能是填写表单),表单的数据在展示层被匹配为VO。
    
            展示层把VO转换为服务层对应方法所要求的DTO,传送给服务层。
    
            服务层首先根据DTO的数据构造(或重建)一个DO,调用DO的业务方法完成具体业务。
    
             服务层把DO转换为持久层对应的PO(可以使用ORM工具,也可以不用),调用持久层的持久化方法,把PO传递给它,完成持久化操作。
    

    2、VO与DTO的区别?

    大家可能会有个疑问(在笔者参与的项目中,很多程序员也有相同的疑惑):既然
    DTO是展示层与服务层之间传递数据的对象,为什么还需要一个VO呢?对!对于绝
    大部分的应用场景来说,DTO和VO的属性值基本是一致的,而且他们通常都是
    POJO,因此没必要多此一举,但不要忘记这是实现层面的思维,对于设计层面来
    说,概念上还是应该存在VO和DTO,因为两者有着本质的区别,DTO代表服务层需
    要接收的数据和返回的数据,而VO代表展示层需要显示的数据。
           用一个例子来说明可能会比较容易理解:例如服务层有一个getUser的方法返回一
    个系统用户,其中有一个属性是gender(性别),对于服务层来说,它只从语义上定
    义:1-男性,2-女性,0-未指定,而对于展示层来说,它可能需要用“帅哥”代表男
    性,用“美女”代表女性,用“秘密”代表未指定。说到这里,可能你还会反驳,在服务
    层直接就返回“帅哥美女”不就行了吗?对于大部分应用来说,这不是问题,但设想一
    下,如果需求允许客户可以定制风格,而不同风格对于“性别”的表现方式不一样,又
    或者这个服务同时供多个客户端使用(不同门户),而不同的客户端对于表现层的要
    求有所不同,那么,问题就来了。再者,回到设计层面上分析,从职责单一原则来
    看,服务层只负责业务,与具体的表现形式无关,因此,它返回的DTO,不应该出现
    与表现形式的耦合。
    
           理论归理论,这到底还是分析设计层面的思维,是否在实现层面必须这样做呢?
    一刀切的做法往往会得不偿失,下面我马上会分析应用中如何做出正确的选择。
    

    VO与DTO的应用

    在以下才场景中,我们可以考虑把VO与DTO二合为一(注意:是实现层面):
    当需求非常清晰稳定,而且客户端很明确只有一个的时候,没有必要把VO和DTO区
    分开来,这时候VO可以退隐,用一个DTO即可,为什么是VO退隐而不是DTO?
    回到设计层面,服务层的职责依然不应该与展示层耦合,所以,对于前面的例子,
    你很容易理解,DTO对于“性别”来说,依然不能用“帅哥美女”,
    这个转换应该依赖于页面的脚本(如JavaScript)或其他机制(JSTL、EL、CSS)
    即使客户端可以进行定制,或者存在多个不同的客户端,
    如果客户端能够用某种技术(脚本或其他机制)实现转换,同样可以让VO退隐
    
    以下场景需要优先考虑VO、DTO并存:
    上述场景的反面场景
    因为某种技术原因,比如某个框架(如Flex)提供自动把POJO转换为UI中某些Field
    时,可以考虑在实现层面定义出VO,这个权衡完全取决于使用框架的自动转换能力
    带来的开发和维护效率提升与设计多一个VO所多做的事情带来的开发和维护效率的
    下降之间的比对。
    如果页面出现一个“大视图”,而组成这个大视图的所有数据需要调用多个服务,返回
    多个DTO来组装(当然,这同样可以通过服务层提供一次性返回一个大视图的DTO来
    取代,但在服务层提供一个这样的方法是否合适,需要在设计层面进行权衡)。
    

    3、DTO与DO的区别?

    首先是概念上的区别,DTO是展示层和服务层之间的数据传输对象(可以认为是两者
    之间的协议),而DO是对现实世界各种业务角色的抽象,这就引出了两者在数据上
    的区别,例如UserInfo和User(对于DTO和DO的命名规则,请参见笔者前面的一篇
    博文),对于一个getUser方法来说,本质上它永远不应该返回用户的密码,因此
    UserInfo至少比User少一个password的数据。而在领域驱动设计中,正如第一篇系列
    文章所说,DO不是简单的POJO,它具有领域业务逻辑。
    

    4、DO与PO的区别?

        DO和PO在绝大部分情况下是一一对应的,PO是只含有get/set方法的POJO,
       但某些场景还是能反映出两者在概念上存在本质的区别:
    
    1、 DO在某些场景下不需要进行显式的持久化,例如利用策略模式设计的商品折扣策
    略,会衍生出折扣策略的接口和不同折扣策略实现类,这些折扣策略实现类可以算是
    DO,但它们只驻留在静态内存,不需要持久化到持久层,因此,这类DO是不存在对
    应的PO的。
    
    2、 同样的道理,某些场景下,PO也没有对应的DO,例如老师Teacher和学生
    Student存在多对多的关系,在关系数据库中,这种关系需要表现为一个中间表,也
    就对应有一个TeacherAndStudentPO的PO,但这个PO在业务领域没有任何现实的意
    义,它完全不能与任何DO对应上。这里要特别声明,并不是所有多对多关系都没有
    业务含义,这跟具体业务场景有关,例如:两个PO之间的关系会影响具体业务,并
    且这种关系存在多种类型,那么这种多对多关系也应该表现为一个DO,又如:“角
    色”与“资源”之间存在多对多关系,而这种关系很明显会表现为一个DO——“权限”。
    
    
    3、某些情况下,为了某种持久化策略或者性能的考虑,一个PO可能对应多个DO,
    反之亦然。例如客户Customer有其联系信息Contacts,这里是两个一对一关系的
    DO,但可能出于性能的考虑(极端情况,权作举例),为了减少数据库的连接查询
    操作,把Customer和Contacts两个DO数据合并到一张数据表中。反过来,如果一本
    图书Book,有一个属性是封面cover,但该属性是一副图片的二进制数据,而某些查
    询操作不希望把cover一并加载,从而减轻磁盘IO开销,同时假设ORM框架不支持属
    性级别的延迟加载,那么就需要考虑把cover独立到一张数据表中去,这样就形成一
    个DO对应对个PO的情况。
    
    4、PO的某些属性值对于DO没有任何意义,这些属性值可能是为了解决某些持久化
    策略而存在的数据,例如为了实现“乐观锁”,PO存在一个version的属性,这个
    version对于DO来说是没有任何业务意义的,它不应该在DO中存在。同理,DO中也
    可能存在不需要持久化的属性。
    

    转自:https://www.cnblogs.com/wang-meng/p/5645405.htmlhttp://www.xuebuyuan.com/746625.html

    相关文章

      网友评论

      本文标题:Java中 VO、 PO、DO、DTO、 BO、 QO、DAO、

      本文链接:https://www.haomeiwen.com/subject/qcbwsftx.html