DTO,VO,POJO,JavaBeans之间的区别?


Answers:


848

JavaBeans

JavaBean是遵循Sun定义的JavaBeans约定的类。Wikipedia很好地总结了什么是JavaBean

JavaBean是Java的可重用软件组件,可以在构建器工具中直观地对其进行操作。实际上,它们是用Java编程语言编写的,符合特定约定的类。它们用于将许多对象封装到单个对象(bean)中,以便可以将它们作为单个bean对象而不是多个单个对象传递。JavaBean是可序列化的Java对象,具有null构造函数,并允许使用getter和setter方法访问属性。

为了充当JavaBean类,对象类必须遵守有关方法命名,构造和行为的某些约定。这些约定使拥有可以使用,重用,替换和连接JavaBean的工具成为可能。

所需的约定为:

  • 该类必须具有公共默认构造函数。这样可以在编辑和激活框架内轻松实例化。
  • 必须遵循标准命名约定,使用get,set和其他方法(所谓的accessor方法和mutator方法)访问类属性。这样可以轻松自动地检查和更新框架中的Bean状态,其中许多框架都包含针对各种类型的属性的自定义编辑器。
  • 该类应可序列化。这允许应用程序和框架以独立于VM和平台的方式可靠地保存,存储和还原Bean的状态。

因为这些需求主要通过约定而不是通过实现接口来表达,所以某些开发人员将JavaBeans视为遵循特定命名约定的Plain Old Java Object。

POJO

普通旧Java对象或POJO是最初引入的一个术语,用于指定一个简单的轻量级Java对象,而不实现任何javax.ejb接口,而不是重量级的EJB 2.x(尤其是实体Bean,无状态会话Bean并不是那么糟糕的IMO)。今天,该术语用于任何没有多余东西的简单对象。同样,维基百科在定义POJO方面做得很好:

POJO是Plain Old Java Object的首字母缩写。该名称用来强调所讨论的对象是普通的Java对象,而不是特殊的对象,尤其不是Enterprise JavaBean(尤其是在EJB 3之前)。这个词是2000年9月由Martin Fowler,Rebecca Parsons和Josh MacKenzie创造的:

“我们想知道为什么人们不反对在他们的系统中使用常规对象,并得出结论,这是因为简单对象缺乏奇特的名称。所以我们给了他们一个名称,并且非常流行。”

对于未使用新功能的技术,例如电话中的POTS(普通老式电话服务)和C ++中定义但仅使用C语言功能的PODS(普通老式数据结构),该术语延续了较旧术语的模式。和Perl中的POD(普通旧文档)。

该术语很可能已被广泛接受,因为需要与复杂的对象框架形成对比的通用且易于理解的术语。JavaBean是可序列化的POJO,具有无参数构造函数,并允许使用getter和setter方法访问属性。Enterprise JavaBean不是单个类,而是整个组件模型(同样,EJB 3降低了Enterprise JavaBeans的复杂性)。

随着使用POJO的设计变得越来越普遍,出现了为POJO提供框架中使用的某些功能以及可以选择哪些功能领域的更多选择的系统。Hibernate和Spring是示例。

价值对象

值对象或VO是诸如java.lang.Integer持有值之类的对象(因此为值对象)。对于更正式的定义,我经常参考Martin Fowler对Value Object的描述:

在《企业应用程序体系结构模式》中,我将值对象描述为一个小对象,例如货币或日期范围对象。它们的关键特性是它们遵循值语义而不是引用语义。

您通常可以告诉他们,因为它们的相等性概念不是基于身份的,而是如果两个值对象的所有字段都相等,则它们相等。尽管所有字段都相等,但是如果子集是唯一的,则无需比较所有字段-例如,货币对象的货币代码足以测试相等性。

一般的启发式方法是价值对象应该完全不可变。如果要更改值对象,则应使用新对象替换该对象,并且不允许更新该值对象本身的值-可更新的值对象会导致混叠问题。

早期的J2EE文献使用术语“值对象”来描述不同的概念,我称之为数据传输对象。此后,他们改变了用法,改用术语“ 传输对象”

您可以在WikiDirk Riehle的有价值的对象上找到更多的好材料。

数据传输对象

数据传输对象或DTO是EJB引入的(反)模式。它不是在EJB上执行许多远程调用,而是将数据封装在可以通过网络传输的值对象中:数据传输对象。维基百科对数据传输对象有一个不错的定义:

数据传输对象(DTO),以前称为值对象或VO,是一种设计模式,用于在软件应用程序子系统之间传输数据。DTO通常与数据访问对象结合使用,以从数据库中检索数据。

数据传输对象与业务对象或数据访问对象之间的区别在于,DTO除了存储和检索自己的数据(访问者和变异者)外,没有其他行为。

在传统的EJB架构中,DTO具有双重目的:首先,它们解决了实体bean无法序列化的问题;其次,它们隐式定义一个组装阶段,在该阶段中,将视图使用的所有数据都提取并编组到DTO中,然后再将控制权返回到表示层。


因此,对于许多人来说,DTO和VO是同一回事(但Fowler使用VO表示我们所看到的其他含义)。大多数时候,它们遵循JavaBeans约定,因此也是JavaBean。而且都是POJO。


1
因此,如果我创建了一个便利类,专门用于class SomeClass { public String foo;public String bar; }在具有许多复杂逻辑的类中传输不相关的数据,例如此类,以确保它不是JavaBean,则不能是VO,因为它是可变的,是否可能是DTO?注意,它不是针对任何形式的远程调用的。可以认为它是POJO吗?
Jaime Hablutzel 2014年

3
@ user2601512:仍然是Bean。:P Bean的行为没有错-实际上,这是人们所期望的。如果它什么都不做,则基本上就是DTO。
cHao 2014年

7
@xSNRG:部分是因为它将对象降级为其他代码所作用的数据。从面向对象的角度来看,这是倒退的一步,在这种情况下,对象将采取行动并应对自己的状态负责。如果您实际上只是在传输数据(因此得名),DTO有时是一个不错的解决方案,但是封装基本上不合时宜,并且您通常会失去真实对象可以提供的任何有效性/一致性保证。
cHao

1
@KumaresanPerumal:如果可以,可以。但是该模型与数据层不同,并且具有不同的目标和规则。数据层通常需要所有已布置并且可以任意设置的内容,并且理想情况下,该模型希望隐藏数据并强制执行不变式。您要使用模型对象进行存储,则必须在一侧或另一侧妥协。
cHao

1
@KumaresanPerumal:数据层用于存储和检索数据。为此,几乎所有对象都需要完全访问拥有数据的任何对象,因为检索意味着在某个位置的对象中设置值。但是该模型管理着系统内的数据,并受到诸如封装之类的面向对象原则的约束,即对象应保持对其内部状态的控制,而不会让其他代码随意地扰乱内部。DTO可以弥补这一差距。数据层可以随意访问它们,并且模型不必放弃控制权。
cHao

66

DTO与VO

DTO-数据传输对象仅仅是用于在层和层之间传输数据的数据容器。

  • 它主要包含属性。您甚至可以使用没有getter和setter的公共属性。
  • 数据传输对象不包含任何业务逻辑。

类推:
具有属性用户名,密码和电子邮件ID的简单注册表单。

  • 在RegistrationServlet文件中提交此表单后,您将获得从视图层到业务层的所有属性,然后在其中将属性传递给Java Bean,然后传递给DAO或持久层。
  • DTO帮助将属性从视图层传输到业务层,最后到持久层。

DTO主要用于有效地跨网络传输数据,甚至可能从JVM到另一个JVM。

DTO通常是java.io.Serializable-为了跨JVM传输数据。

VO-值对象[1] [2]本身表示一组固定的数据,并且类似于Java枚举。值对象的身份基于其状态而不是对象的身份,并且是不可变的。真实的示例是Color.RED,Color.BLUE,SEX.FEMALE等。

POJO与JavaBeans

[1] POJO的Java-Beanness是,所有私有属性都可以通过符合JavaBeans约定的公共getter和setter进行访问。例如

    private String foo;
    public String getFoo(){...}
    public void setFoo(String foo){...}; 

[2] JavaBeans必须实现Serializable并且具有无参数构造函数,而在POJO中则没有这些限制。


抱歉,这么晚才发表评论,但我正在了解它们之间的区别,我有一个问题。如果我有一个Java Bean类,但又带有doSomething()这样的其他方法,该怎么办。这是什么样的课程?问候
jscherman 2014年

@srinivas为什么我们不能在DOMAIN或MODEL Java对象中传递数据?但是我使用没有DTO的MODEL。请简要解释一下。谢谢
Kumaresan Perumal

46

基本上,

DTO:“数据传输对象”可以在软件体系结构的不同层之间传播。

VO:“值对象”包含一个对象,例如Integer,Money等。

POJO:普通的旧Java对象,不是特殊对象。

Java Bean:要求Java Class可序列化,no-arg每个字段都有一个构造函数以及一个getter和setter


这些描述大多是错误的/不完整的。
cellepo

24

Java Bean与EJB不同。

Java 1.0中的JavaBeans规范是Sun尝试允许在看起来像VB的IDE中操纵Java对象的方法。对于合格为“ Java Bean”的对象,制定了一些规则:

  1. 默认构造函数
  2. 遵循正确命名约定的私有数据成员的获取器和设置器
  3. 可序列化
  4. 也许其他人我忘记了。

EJB后来问世。它们将分布式组件和事务模型结合在一起,并在管理线程,池化,生命周期和提供服务的容器中运行。它们与Java Beans相去甚远。

DTO是在Java上下文中出现的,因为人们发现EJB 1.0规范对于数据库太“闲谈”了。人们可以将它们打包成Java Bean并随身携带,而不是对每个数据元素进行往返。

POJO是对EJB的一种反应。


1
我错了,我希望删除我的信息。感谢您的指正。我想注意到POJO的含义已经改变了一段时间。首先,它们仅由私有财产及其访问者组成。现在,我们考虑一个POJO与注解类,实施和扩展其他类,等等
sinuhepop

如问题所问,VO呢?这不是一个答案,直到它回答了完整的问题
cellepo

4

POJO:这是一个Java文件(类),不会扩展或实现任何其他Java文件(类)。

Bean:这是一个Java文件(类),其中所有变量都是私有的,方法是公共的,并且使用适当的getter和setter来访问变量。

普通类:这是一个Java文件(类),可以由公共/私有/默认/受保护的变量组成,并且可以扩展也可以不扩展或实现另一个Java文件(类)。


如问题所问,VO呢?这不是一个答案,直到它回答了完整的问题
cellepo

1

先说说

普通类 -这意味着任何类在Java中的定义都是正常的,这意味着您创建了不同类型的方法属性
。Bean- Bean并不是什么,它只是使用该bean的那个特定类的对象,您可以像访问对象一样访问java类。

然后谈论最后一个POJO

POJO - POJO是没有任何服务的类,它只有一个默认构造函数和private属性,以及用于设置与setter和getter方法相对应的值的那些属性。它是Plain Java Object的简称。


如问题所问,VO呢?这不是一个答案,直到它回答了完整的问题
cellepo

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.