DTO,VO,POJO,JavaBeans之间的区别?
已经看到一些类似的问题:
- JavaBean和POJO有什么区别?
- POJO(简单的旧Java对象)和DTO(数据传输对象)之间的区别是什么?
你能不能告诉我他们使用的背景? 还是他们的目的?
的JavaBeans
JavaBean是一个遵循Sun定义的JavaBeans约定的类。 维基百科有一个相当不错的JavaBeans摘要:
JavaBeans是可重用的Java软件组件,可以在构建器工具中直观地操作。 实际上,它们是以符合特定约定的Java编程语言编写的类。 它们被用来将许多对象封装到一个对象(bean)中,以便它们可以作为一个单独的bean对象而不是多个单独的对象传递。 JavaBean是一个Java对象,它是可序列化的,有一个无限的构造函数,并允许使用getter和setter方法访问属性。
为了用作JavaBean类,对象类必须遵守有关方法命名,构造和行为的某些约定。 这些约定使拥有可以使用,重用,替换和连接JavaBeans的工具成为可能。
所需的约定是:
- 该类必须有一个公共的默认构造函数。 这允许在编辑和激活框架内容易实例化。
- 按照标准命名约定,类属性必须可以使用get,set和其他方法(所谓的访问器方法和增变器方法)进行访问。 这允许在框架内轻松自动检查和更新bean状态,其中许多包括各种属性的自定义编辑器。
- 这个类应该是可序列化的。 这允许应用程序和框架以独立于VM和平台的方式可靠地保存,存储和恢复bean的状态。
由于这些需求主要表示为约定而不是通过实现接口,因此一些开发人员将JavaBeans视为遵循特定命名约定的普通旧Java对象。
POJO
简单的旧Java对象或POJO是最初引入的术语,用于指定一个简单的轻量级Java对象,而不是实现任何javax.ejb
接口,而不是重量级的EJB 2.x(特别是实体Bean,无状态会话Bean并不是那么糟糕的IMO) 。 今天,这个术语是用于任何简单的对象,没有额外的东西。 再一次,维基百科在定义POJO方面做得很好:
POJO是Plain Old Java Object的缩写。 该名称用于强调所讨论的对象是一个普通的Java对象,而不是一个特殊的对象,特别是不是一个Enterprise JavaBean(特别是在EJB 3之前)。 这个词是由Martin Fowler,Rebecca Parsons和Josh MacKenzie在2000年9月创造的:
“我们想知道为什么人们在他们的系统中使用常规物体是如此的反对,并得出结论,那是因为简单的物体没有一个奇特的名字,所以我们给了他们一个,而且很好地捕捉到了。
该术语继续使用旧技术的术语模式,这些技术不使用新技术,例如电话中的POTS(普通老式电话服务),以及C ++中定义的PODS(普通旧数据结构),但只使用C语言功能,和Perl中的POD(Plain Old Documentation)。
这个术语最有可能得到广泛的接受,因为需要一个与复杂的对象框架形成对比的通俗易懂的术语。 JavaBean是一个可序列化的POJO,具有无参数的构造函数,并允许使用getter和setter方法访问属性。 Enterprise JavaBean不是一个类,而是一个完整的组件模型(同样,EJB 3降低了Enterprise JavaBeans的复杂性)。
随着使用POJO的设计变得越来越常用,系统已经出现,使得POJO在框架中使用了一些功能,并且更多地选择了实际需要哪些功能领域。 Hibernate和Spring就是例子。
价值对象
值对象或VO是一个对象,如java.lang.Integer
,它保存值(因此为值对象)。 对于一个更正式的定义,我经常提到Martin Fowler对价值对象的描述:
在企业应用程序体系结构的模式中,我将Value Object描述为一个小对象,例如Money或日期范围对象。 它们的关键属性是它们遵循价值语义而不是引用语义。
你通常可以告诉他们,因为他们的平等观念不是基于身份,而是两个价值对象是相等的,如果他们的所有领域是平等的。 尽管所有字段都是相同的,但是如果一个子集是唯一的,则不需要比较所有字段 – 例如货币对象的货币代码就足以测试相等性。
一般的启发式是值对象应该是完全不变的。 如果要更改值对象,则应该用新对象替换对象,而不允许更新值对象本身的值 – 可更新值对象会导致混叠问题。
早期的J2EE文献使用术语值对象来描述不同的概念,我称之为数据传输对象 。 他们已经改变了他们的用法,并使用了“ 转移对象 ”一词。
你可以在wiki上找到更多关于价值对象的更好的材料,也可以找到Dirk Riehle 。
数据传输对象
数据传输对象或DTO是EJB引入的(反)模式。 不是在EJB上执行很多远程调用,而是将数据封装在可以通过网络传输的值对象中:数据传输对象。 维基百科有一个体面的数据传输对象的定义:
数据传输对象(DTO),以前称为值对象或VO,是用于在软件应用程序子系统之间传输数据的设计模式。 DTO通常与数据访问对象一起使用来从数据库检索数据。
数据传输对象与业务对象或数据访问对象之间的区别在于DTO除了存储和检索自己的数据(访问器和增变器)之外没有任何行为。
在传统的EJB体系结构中,DTO有两个目的:第一,解决实体bean不可序列化的问题; 其次,它们隐含地定义了一个汇编阶段,在这个阶段中,在将控制权返回到表示层之前,视图所使用的所有数据都被提取并编组到DTO中。
所以,对于很多人来说,DTO和VO是一回事(但是福勒使用VO来表示我们看到的其他东西)。 大多数时候,他们遵循JavaBeans约定,因此也是JavaBeans。 而且都是POJO。
DTO vs 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 vs JavaBeans
[1] POJO的Java-Beanness是它的私有属性都是通过符合JavaBeans约定的公共getter和setter来访问的。 例如
private String foo; public String getFoo(){...} public void setFoo(String foo){...};
[2] JavaBeans必须实现Serializable并且有一个无参数的构造函数,在POJO中没有这些限制。
基本上,
DTO:“数据传输对象”可以在软件架构中的不同层之间传输。
VO:“价值对象”持有Integer,Money等对象
POJO:普通旧Java对象,它不是一个特殊的对象。
Java Beans:需要一个Java Class
是可序列化的,有一个no-arg
构造函数,每个字段有一个getter和setter
Java Beans和EJB不是一回事。
Java 1.0中的JavaBeans规范是Sun试图允许Java对象在类似于VB的IDE中进行操作。 有一些规则规定了符合“Java豆类”标准的对象:
- 默认的构造函数
- 专用数据成员的访问者和设置者遵循适当的命名约定
- 序列化
- 也许别人,我忘了。
EJB稍后。 它们结合了分布式组件和事务模型,运行在一个容器中,该容器管理线程,池化,生命周期并提供服务。 它们与Java Beans相差甚远。
DTO出现在Java环境中,因为人们发现EJB 1.0规范对数据库太“唠叨”了。 人们不会为了每个数据元素而往返,而是将它们批量包装到Java Beans中,并将它们运送到周围。
POJO是对EJB的反应。
POJO :这是一个java文件(类),它不扩展或实现任何其他的Java文件(类)。
Bean :这是一个java文件(类),其中所有的变量都是私有的,方法是公共的,适当的getter和setter用于访问变量。
普通类 :它是一个可以由public / private / default / protected变量组成的java文件(类),可以扩展或者实现另一个java文件(class)。