关于命名你真的懂吗?–JavaBean\Domain\Entity\POJO的区别
关于命名你真的懂吗?–JavaBean\Domain\Entity\POJO的区别
文章目录
JavaBean(Java 豆子)
在 JavaBeans API specification中这样写到:
The goal of the JavaBeans APIs is to define a software component model for Java, so that third party ISVs can create and ship Java components that can be composed together into applications by end users.
由来
Java语言欠缺属性、事件、多重继承功能。所以,如果要在Java程序中实现一些面向对象编程的常见需求,只能手写大量胶水代码。Java Bean正是编写这套胶水代码的惯用模式或约定。这些约定包括getXxx、setXxx、isXxx、addXxxListener、XxxEvent等。遵守上述约定的类可以用于若干工具或库。
举个例子,假如有人要用Java实现一个单向链表类,可能会这样写:
// 编译成 java-int-list_1.0.jar
public final class JavaIntList {
static class Node {
public Node next;
public int value;
}
public Node head;
public int size;
}
上述实现为了能够快速获取链表的大小,把链表大小缓存在size变量中。用法如下:
JavaIntList myList = new JavaIntList();
System.out.println(myList.size);
JavaIntList的作者很满意,于是开源了java-int-list库的1.0版。文件名是java-int-list_1.0.jar。发布后,吸引了许多用户来使用java-int-list_1.0.jar。
有一天,作者决定要节省内存,不要缓存size变量了,把代码改成这样:
// 编译成 java-int-list_2.0.jar
public final class JavaIntList {
static final class Node {
public Node next;
public int value;
}
public Node head;
public int getSize() {
Node n = head;
int i = 0;
while (n != null) {
n = n.next;
i++;
}
return i;
}
}
然后发布了2.0版:java-int-list_2.0.jar。发布后,原有java-int-list_1.0.jar的用户纷纷升级版本到2.0。这些用户一升级,就发现自己的程序全部坏掉了,说是找不到什么size变量。于是这些用户就把作者暴打一顿,再也不敢用java-int-list库了。
这个故事告诉我们,如果不想被暴打致死,你就必须保持向后兼容性。太阳公司在设计Java语言时,也懂得这个道理。所以Java标准库中,绝对不会出现public int size这样的代码,而一定会一开始就写成:
private int size;
public int getSize() { return size; }
让用户一开始就使用getSize,以便有朝一日修改getSize实现时,不破坏向后兼容性。这种public int getSize() { return size; }的惯用手法,就是Java Bean。
什么是JavaBean?
JavaBean规范:
-
JavaBean 类必须是一个公共类, 即将其访问属性设置为 public, 如: public class Student{…}
-
JavaBean 类必须有一个空的构造函数: 类中必须有一个无参的public构造方法
-
一个JavaBean类不应有公共实例变量, 类变量都为private, 如: private int age;
-
属性应该由一组读写方法(getXxx 和 setXxx)来访问,一般是IDE(Eclipse、IntelliJ IDEA)为属性生成getter/setter 方法
公共类\属性私有\无参构造函数\有get、set方法
JavaBean属性一般以小写字母开头, 使用驼峰命名格式. 相应的 getter/setter 方法是 get/set 接首字母大写的属性名. 例如: 属性名为age, 其对应的getter/setter 方法是 getAge/setAge.
一些特殊情况:
- 如果操作的字段为boolean类型, 此时不应该叫个getter方法, 而是is方法, 例如把getName变成isName.
- 如果属性名的第二个字母大写, 那么该属性名直接用作 getter/setter 方法中 get/set 的后部分, 就是说大小写不变. 例如属性名为sName,方法是getsName/setsName.
- 如果前两个字母是大写(专有名词和缩略词等), 这种情况属性名直接接在 getter/setter 方法中 get/set 的后部分. 例如属性名为URL, 方法是getURL/setURL.
- 如果首字母大写,也是属性名直接接在 getter/setter 方法中 get/set 的后部分. 例如属性名为Name, 方法是getName/setName, 这种情况会出问题, 会因为找不到属性而出错: 因为默认的属性名是name.
基于JavaBean规范,很多框架利用反射实现数据与java对象的转换
Domain(域)
领域类是什么鬼?领域不是field吗?
Oxford Dict中的解释是,domain源自于法语domeine,原意是estate, belonging to a lord,后来引进英语主要指an area of territory。domain在计算机方向有两个解释:
-
来自于数学术语,the set of possible values of the independent variable or variables of a function.
-
因特网,a distinct subset of the Internet with addresses sharing a common suffix.
因特网这个比较好理解,网站也叫site,所以网域是借助了an area of territory的含义。而编程中的domain主要来自数学上的含义,在数据库设计中,是指一个独立的数据类型能够包含的全部取值范围。我们知道OOP中都是值传递,Java Bean就是对值的封装,它的所有取值范围就被抽象成类,和数据库中的表对应,表的一条记录又对应一个对象,那一张表所有可能的记录就是它的domain,也就是说,不同的类就是不同的domain(所有取值的集合),因此Java Bean,Entity,POJO,domain model说的其实是一个东西,而且从这个意义上也很容易将对象理解成map。
顺便提一下哲学上的解释也很有意思。中文里"范围"被翻译为scope,range或limits,而domain被翻译为"范畴",与category同义,是指哲学中对所有存在最广义的分类,是分类的最高层次的统称,是人的思维对客观事物的普遍本质的概括。所以你看,domain正好契合了OOP中一切皆是对象的思想。
Entity
实体关系模型(或ER 模型)描述了特定知识领域中相互关联的兴趣事物。基本的 ER 模型由实体类型(对感兴趣的东西进行分类)组成,并指定实体之间可能存在的关系(这些实体类型的实例)。
使用陈的符号为MMORPG绘制的实体属性关系图。
在软件工程中,ER 模型通常代表企业执行业务流程时需要记住的东西。因此,ER模型成为一个抽象的数据模型,定义一个数据或信息结构,可以在数据库中实现,通常是一个关系数据库。
实体关系建模是由Peter Chen为数据库和设计而开发的,发表在1976年的一篇论文中[,1]与以前存在的想法的变体。 [2]一些 ER 模型显示由泛化-专业化关系连接的超级和亚型实体[,3]和 ER 模型也可用于特定领域本体论的规范。
POJO
POJO(Plain Ordinary Java Object)简单的Java对象,实际就是普通JavaBeans,是为了避免和EJB混淆所创造的简称。
使用POJO名称是为了避免和EJB混淆起来, 而且简称比较直接. 其中有一些属性及其getter setter方法的类,没有业务逻辑,有时可以作为VO(value -object)或dto(Data Transform Object)来使用.当然,如果你有一个简单的运算属性也是可以的,但不允许有业务方法,也不能携带有connection之类的方法。
VO
value object:值对象
通常用于业务层之间的数据传递,由new创建,由GC回收。
PO
persistant object:持久层对象
对应数据库中表的字段。
VO和PO,都是属性加上属性的get和set方法;表面看没什么不同,但代表的含义是完全不同的。
DTO
data transfer object:数据传输对象。
表里面有十几个字段:id,name,gender(M/F),age,conmpanyId(如001)…
页面需要展示四个字段:name,gender(男/女),age,conmpanyName(如今日头条股份有限公司)。
DTO由此产生,一是能提高数据传输的速度(减少了传输字段),二能隐藏后端表结构。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J1fZyiqP-1616656839072)(JAVA%E5%91%BD%E5%90%8D.assets/6ef500025174c9ec01e4.png)]
BO
business object:业务对象
BO把业务逻辑封装为一个对象。
我理解是PO的组合,比如投保人是一个PO,被保险人是一个PO,险种信息是一个PO等等,他们组合起来是第一张保单的BO。
POJO
plain ordinary java object:简单无规则java对象
纯的传统意义的java对象,最基本的Java Bean只有属性加上属性的get和set方法。
可以转化为PO、DTO、VO;比如POJO在传输过程中就是DTO。
java对象
纯的传统意义的java对象,最基本的Java Bean只有属性加上属性的get和set方法。
可以转化为PO、DTO、VO;比如POJO在传输过程中就是DTO。