Discuz! Board

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 2409|回复: 3
打印 上一主题 下一主题

Java bean 是个什么概念?

[复制链接]

32

主题

53

帖子

202

积分

认证用户组

Rank: 5Rank: 5

积分
202
跳转到指定楼层
楼主
发表于 2017-2-28 22:27:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
作者:杨博
链接:https://www.zhihu.com/question/19773379/answer/31625054
来源:知乎
著作权归作者所有,转载请联系作者获得授权。

Java语言欠缺属性、事件、多重继承功能。所以,如果要在Java程序中实现一些面向对象编程的常见需求,只能手写大量胶水代码。Java Bean正是编写这套胶水代码的惯用模式或约定。这些约定包括getXxx、setXxx、isXxx、addXxxListener、XxxEvent等。遵守上述约定的类可以用于若干工具或库。

举个例子,假如有人要用Java实现一个单向链表类,可能会这样写:
// 编译成 java-int-list_1.0.jarpublic 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.jarpublic 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。

现在是2014年,C#、Scala等比Java新的面向对象语言自身就提供了语言特性来实现这些常用需求,所以根本不需要Java Bean这样繁琐的约定。

比如,假如有个Scala版的ScalaIntList:
// 编译成 scala-int-list_1.0.jarobject ScalaIntList {  final case class Node(next: Node, value: Int)}final class ScalaIntList {  var head: ScalaIntList.Node = null  var size: Int = 0}
用户这样用:
val myList = new ScalaIntListprintln(myList.size)
有一天你心血来潮改成这样:
// 编译成 scala-int-list_2.0.jarobject ScalaIntList {  final case class Node(next: Node, value: Int)}final class ScalaIntList {  var head: ScalaIntList.Node = null  final def size: Int = {    var n = head    var i = 0    while (n != null) {      n = n.next      i++    }    i  }}
用户还是照样能用,根本不破坏向后兼容性。所以Scala程序只要不考虑和Java交互,一般就不需要类似Java Bean这样的约定。

顺便说一句,向后兼容性分为源代码级和二进制级,Scala的var或val改为final def的话,无论源代码级的向后兼容性,还是二进制级的向后兼容性,都不遭受破坏。但C#的字段改为属性的话,虽然不破坏源代码级的向后兼容性,但是会破坏二进制级的向后兼容性。这是C#的设计缺陷,导致微软的编码规范不得不禁止使用公有字段。


回复

使用道具 举报

32

主题

53

帖子

202

积分

认证用户组

Rank: 5Rank: 5

积分
202
沙发
 楼主| 发表于 2017-2-28 22:28:19 | 只看该作者
1、所有属性为private
2、提供默认构造方法
3、提供getter和setter
4、实现serializable接口
回复 支持 反对

使用道具 举报

32

主题

53

帖子

202

积分

认证用户组

Rank: 5Rank: 5

积分
202
板凳
 楼主| 发表于 2017-2-28 22:33:34 | 只看该作者
作者:文朋
链接:https://www.zhihu.com/question/19773379/answer/18307751
来源:知乎
著作权归作者所有,转载请联系作者获得授权。

最近又在看<spring in action>,里面很详细讲解上面名词来历:
  • 在java1996年发布,当年12月即发布了java bean1.00-A,有什么用呢?通过统一的规范可以设置对象的值(get,set方法),这是最初的java bean;
  • 在实际企业开发中,需要实现事务,安全,分布式,javabean就不好用了.sun公司就开始往上面堆功能,这里java bean就复杂为EJB;
  • EJB功能强大,但是太重了.此时出现DI(依赖注入),AOP(面向切面)技术,通过简单的java bean也能完成EJB的事情,这里的java bean简化为POJO(Plain Ordinary Java Object)简单的Java对象,实际就是普通JavaBeans,是为了避免和EJB混淆所创造的简称。;
  • Spring诞生了.
----------这里是分隔线 2016年03月13日更新------

随着自己参与项目积累的增加,又接触几种,这里补充一些.
  • PO(persistence object):用于持久化时(例如保存到数据库或者缓存);
  • VO(value object):用于前端展示使用(例如放置到JSP中解析或者给前端传递数据)
  • DTO(data transfer object):用于接口互相调用返回,数据传输(例如很多接口调用返回值或消息队列内容);
特别地,由于class不同,复制时一般推荐 Dozer · springside/springside4 Wiki · GitHub.

----------这里是分隔线 2016年06月13日更新------

这里规范有一个小坑:属性名ICar是合法的,但iCar是非法的..有一个要求(属性前两个字母大小写必须一致)主要是get和set方法无法区分.上面两个属性set方法都是SetICar()


----------这里是分隔线 2014年12月19日以前的答案------

从Stack Overflow看到的答案,我觉得应该能完美回答你:
主要区分三个:JavaBean,EJB,POJO。
JavaBean
JavaBean是公共Java类,但是为了编辑工具识别,需要满足至少三个条件:
  • 有一个public默认构造器(例如无参构造器,)
  • 属性使用public 的get,set方法访问,也就是说设置成private,同时get,set方法与属性名的大小也需要对应。例如属性name,get方法就要写成,public String getName(){},N大写。
  • 需要序列化。这个是框架,工具跨平台反映状态必须的
最近看<Think in Java>,里面讲到JavaBean最初是为Java GUI的可视化编程实现的.你拖动IDE构建工具创建一个GUI 组件(如多选框),其实是工具给你创建java类,并提供将类的属性暴露出来给你修改调整,将事件监听器暴露出来.《java 编程思想(第四版)》p823-824
EJB
在企业开发中,需要可伸缩的性能和事务、安全机制,这样能保证企业系统平滑发展,而不是发展到一种规模重新更换一套软件系统。 然后有提高了协议要求,就出现了Enterprise Bean。
EJB在javabean基础上又提了一些要求,当然更复杂了。
POJO
有个叫Josh MacKenzie人觉得,EJB太复杂了,完全没必要每次都用,所以发明了个POJO,POJO是普通的javabean,什么是普通,就是和EJB对应的。
      总之,区别就是,你先判断是否满足javabean的条件,然后如果再实现一些要求,满足EJB条件就是EJB,否则就是POJO。
原文链接:java - Difference between DTO, VO, POJO, JavaBeans?


回复 支持 反对

使用道具 举报

32

主题

53

帖子

202

积分

认证用户组

Rank: 5Rank: 5

积分
202
地板
 楼主| 发表于 2017-2-28 22:44:31 | 只看该作者
对于j2ee(Java 2 Platform Enterprise Edition Java2平台企业版)的初学者,javabean确实是一个让人容易困惑的概念。
现在来说说我自己的理解。

javabean其实包含多个方面的含义。

1,顾名思义,bean,保存数据的实体,通常与数据库中的表对应。也称为,pojo,entity,domain。比如Person,Apple等,只有private属性和public setxxxx和getxxx。具体实例就是对应表中的一行。那些hibernate,ibatis等orm框架,都支持它们和表的互相映射。

2,这个就比较高大上,也比较抽象了。javabean被称为完成特定功能的组件。不是有高内聚低耦合的说法么?它就是这样一组java类集合。

纯属个人理解。


作者:林子云
链接:https://www.zhihu.com/question/19773379/answer/31643984
来源:知乎
著作权归作者所有,转载请联系作者获得授权。

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|firemail ( 粤ICP备15085507号-1 )

GMT+8, 2024-11-26 07:03 , Processed in 0.058887 second(s), 18 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表