对于没有系统学习过java开发的人来说,很多名词都是感觉熟悉,却说不出个所以然。因为在日常开发中,经常遇到而感觉熟悉,到自己写程序时,却又不确定是不是这么做。这里,我先简单辨析一下JavaBean、POJO、DAO、DTO这几个术语。
JavaBean,就是一个普通的java对象加上下面的属性:
1、必须有一个公开的缺省的无参构造方法
2、所有的属性,必须实现getter、setter、is(针对布尔类型来访问)
3、必须实现Serializable接口
所以说,JavaBeans实际上是一套规范,这套规范遵循上面的三个原则。一个典型的JavaBean类如下:
package player;
public class PersonBean implements java.io.Serializable {
// Property <code>name</code> (note capitalization) readable/writable.
private String name = null;
private boolean deceased = false;
/** No-arg constructor (takes no arguments). */
public PersonBean() {}
// Getter for property <code>name</code>
public String getName() {
return name;
}
// Setter for property <code>name</code>.
public void setName(final String value) {
name = value;
}
// Getter for property "deceased" Different syntax for a boolean field (is vs. get)
public boolean isDeceased() {
return deceased;
}
// Setter for property <code>deceased</code>.
public void setDeceased(final boolean value) {
deceased = value;
}
}
这套规范在Java社区是广受认可的,但是这又有什么好处呢?原来可以简单方便的通过public直接访问的属性现在要变成private并通过getter、setter方法访问!
POJO, Plain Old Java Object ,与之对立的就是EJB,POJO的产生是源于EJB的复杂性,在过去做企业开发的时候要实现复杂的java.ejb接口,例如:
public class Bar implements javax.ejb.EntityBean { ...}
而POJO类就是一个简简单单、普普通通的Java类,没有任何附加的强迫的东西:
public class Person {
// Property <code>name</code> (note capitalization) readable/writable.
private String name = null;
// Getter for property <code>name</code>
public String getName() {
return name;
}
// Setter for property <code>name</code>.
public void setName(final String value) {
name = value;
}
}
在Java后期随着语言发展,大家发现基于AOP,依赖注入框架使用POJO类即可完成以前需要EJB才能完成的功能,于是乎大家纷纷转向POJO。POJO最早是 Martin Fowler, Rebecca Parsons 和 Josh MacKenzie (全是业界名人)在 2000年提出的。而 JavaBeans 算是加上了那三个限制条件的POJO类。
DAO,DataAccessObject 的缩写,简单的说,DAO是工作在持久层的,主要负责从底层存储中写入/读取数据,对业务层来说只需要知道DAO的接口即可完成CRUD操作,而不必关心底层的数据存储方式。、
典型的DAO对象会封装增删改查四种操作:
public interface Dao <T> {
/** Persist the newInstance object into database */
int create(T newInstance);
/** Retrieve an object that was previously persisted to the database using
* the indicated id as primary key
*/
T read(int id);
/** Save changes made to a persistent object. */
void update(T transientObject);
/** Remove an object from persistent storage in the database */
void delete(T persistentObject);
}
DAO 模式最早原自于 JavaEE 的
Core J2EE Patterns
标准,DAO内部实现中一般会处理数据库的JDBC等。
虽然DAO模式原生自Java语言,但是这种模式也适用于其他语言,DAO使业务层和持久层可以分别的独立的演进。DAO模式也会带来一些问题,比如代码重复(这也是分层模式最大的问题,各层之间存在大量类似的对象和代码),另外会屏蔽底层耗时的操作,对于业务层的程序员来说,他未必知道每一个DAO操作的时间复杂度,这不利于写出高性能的应用。
DTO 是 Data Transfer Object 的缩写,这种模式源于WebService中的远程调用,为了减少远程调用的次数,可以把数据聚合在一起在一个调用中返回,这样需要一个对象来承载数据,于是便有了DTO。DTO不能有任何的行为和业务逻辑,因为它的存在仅仅是为了承载并聚合数据。
VO 是 ValueObject 的缩写,在很长一段时间内,在Java社区VO和DTO是混淆的。VO一般指代一些很小的,值不会变化的对象 - 值对象(非引用对象)。在Java语言中并没有VO的实现,所以容易误解。在其他语言,比如C#的Struct类型可以很好的演绎。
一般在Java语言中为了实现VO类型,会定义这样的对象。
public final class Foo {
private final String name;
public(String name) {
this.name = name;
}
}
这样从技术层面保证VO对象不会被改变,Java中的Integer,Long,String都属于VO类型。