[整理] Java 的Ejb,JavaBean,DTO,VO,Entity,POJO 等以及分层的概念辨析
1. 概念
1.1 POJO(Plain Old Java Object)
POJO是Martin Fowler等人在2000年的一次演讲的时候提出来的。从字面上翻译为“纯洁老式的java对象”,但大家都使用“简单java对象”来称呼它。
POJO的内在含义是指那些:
- 有一些private的参数作为对象的属性,然后针对每一个参数定义get和set方法访问的接口。
- 没有从任何类继承、也没有实现任何接口,更没有被其它框架侵入的java对象。
public class User {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
1.2 JavaBean
JavaBean 是一种JAVA语言写成的可重用组件,是符合一定规范编写的Java类。不是一种技术,而是一种规范。大家针对这种规范,总结了很多开发技巧、工具函数。符合这种规范的类,可以被其它的程序员或者框架使用。
它的方法命名,构造及行为必须符合特定的约定:
- 所有属性为private。
- 这个类必须有一个公共的缺省构造函数。即是提供无参数的构造器。
- 这个类的属性使用getter和setter来访问,其他方法遵从标准命名规范。
- 这个类应是可序列化的。实现serializable接口。
因为这些要求主要是靠约定而不是靠实现接口,所以许多开发者把JavaBean看作遵从特定命名约定的POJO。
public class UserInfo implements java.io.Serializable{
//实现serializable接口。
private static final long serialVersionUID = 1L;
private String name;
private int age;
//无参构造器
public UserInfo() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//javabean当中可以有其它的方法
public void userInfoPrint(){
System.out.println("");
}
}
两者有什么区别?
- POJO其实是比javabean更纯净的简单类或接口。POJO严格地遵守简单对象的概念,而一些JavaBean中往往会封装一些简单逻辑。
- POJO的格式是用于数据的临时传递,它只能装载数据, 作为数据存储的载体,而不具有业务逻辑处理的能力。
- javabean虽然数据的获取与pojo一样,但是javabean当中可以有其它的方法。
1.3 EJB(Enterprise JavaBean)
EJB: 我认为它是一组"功能"JavaBean的集合。有会话Bean(Session Bean)、实体Bean(Entity Bean)、和消息驱动Bean(MessageDriven Bean)。
上面说了JavaBean是实现了一种规范的Java对象。这里说EJB是一组JavaBean,的意思是这一组JavaBean组合起来实现了某个企业组的业务逻辑。这里的一组JavaBean不是乱组合的,它们要满足能实现某项业务功能的搭配。找个比方,对于一身穿着来说,包括一顶帽子,一件衣服,一条裤子,两只鞋。这穿着就是EJB,其它的就是一个JavaBean。
1.4 关系表示
Entity = Database Table
Model = Entities + Relations
DTO = Entity - Uninteresting Fields
View = DTOs + Relations
1.5 Entity和DO(Data Object)
Entity = DO(Data Object)
有主键标识唯一性,与数据库表字段一一对应。实体bean。
1.6 Model
Model通常表示针对某个问题或业务领域,与真实世界相关的对象。在编程上就是一个有属性有方法的类,和BO业务对象、DDD中的Domain Model领域模型对应。
1.7 DTO(Data Transfer Object)、VO(View Object)、BO(Business Object)
DTO是面向对象(表示层)的,Entity 是面向关系数据库。表示层DTO的是由多个实体构成,或一个实体的一个部分,或多个实体的各个部分的结合体。
是由 Service 层输出的封装业务逻辑的对象。系统和服务之间交互传输用;
BO:POJO在业务层的体现,对于业务操作来说,更多的是从业务上来包装对象。
如一个User的BO,可能包括name, age, sex, privilege, group等,这些属性在数据库中可能会在多张表中,因为每一张表对应一个PO。
而我们的BO需要这些PO组合起来(或说重新拼装)才能成为业务上的一个完整对象。
和VO(View Object)、BO(Business Object)的区别:DTO注重数据传输、VO注重界面展示,BO注重业务逻辑。几个有时候使用可以同一个对象,但意义不一样,复杂的业务或展示时,要区分。
VO和ViewModel差不多,只不过后者用在MVVC模型中。
1.8 PO(persistent object)
我们通过DAO将POJO持久化为PO,用PO组装出来DTO。
总结下,我认为一个对象究竟是什么O要看具体环境,在不同的层、不同的应用场合,对象的身份也不一样,而且对象身份的转化也是很自然的。
就像你对老婆来说就是老公,对父母来说就是子女。
设计这些概念的初衷不是为了唬人而是为了更好的理解和处理各种逻辑,让大家能更好的去用面向对象的方式处理问题。
比如:我们一张表有100个字段,那么对应的PO就有100个属性。但是我们界面上只要显示10个字段,客户端用调用API来获取数据,没有必要把整个PO对象传递到客户端,这时我们就可以用只有这10个属性的DTO来传递结果到客户端,这样也不会暴露服务端表结构。到达客户端以后,如果用这个对象来对应界面显示,那此时它的身份就转为VO。
2. 分层概念
2.1 entity层
- entity 就是属性类,通常定义在model层里面,相当于MVC的 M 层,属于数据模型层
- 一般得实体类对应一个数据表,其中的属性定义数据表中的字段,实体类的字段数量 >= 数据库表中需要操作的字段数量
2.2 DAO层
DAO(data access objects)是数据访问对象,DAO一般有接口和该接口的实现类,接口用于规范实现类。
某个DAO中的实现类一定是和数据库中的某一张表一一对应的,而且其中也只是封装了增删改查得方法。
2.3 service层
service层即为业务逻辑层,可以理解为对一个或者多个DAO进行得再次封装,主要是针对具体的问题的操作,把一些数据层的操作进行组合,间接与数据库打交道(提供操作数据库的方法)。
要做这一层的话,要先设计接口,再实现类。
2.4 controller层
负责请求转发,接收页面过来的参数,传给service处理,接到返回值,并再次传给页面
2.5 mapper层
- 数据存储对象,相当于DAO层,mapper层直接与数据库打交道(执行SQL语句),接口提供给service层。
- 也解决Entity有时候和数据库表不一致的映射问题。因为可能最初是一一对应的,但后面不断改变后不完全对应了。