Java豆:我错过了什么?

我想知道我是否遗漏了一些关于Java Bean的东西。 我喜欢我的对象在构造函数中尽可能多地进行初始化并且具有最少数量的mutator。 豆似乎直接反对这一点,并且通常感到笨重。 我没有将我的对象构建为Beans而错过了哪些function?

听起来你走在正确的轨道上。 并不是你错过了Java Beans的观点,而是其他程序员滥用它们。

Java Beans规范旨在与可视化工具一起使用。 我们的想法是,应用程序设计人员能够以交互方式配置对象的实例,然后对配置的bean进行序列化(或生成代码),以便可以在运行时重建它; 意图是它不会在运行时发生变异。

不幸的是,很多开发人员都不明白访问者是否违反了封装 。 他们使用结构而不是对象。 他们没有看到其他类,甚至其他包有任何错误,依赖于类的数据成员。

当然,您通常需要配置对象的实例。 只是应该通过某种配置function来完成。 这可能是dependency injection容器,“BeanBox”样式可视化工具,或者只是读取您手动编写的JSON,XML或属性文件。 关键是在运行时这些对象实际上是不可变的; 客户只是调用他们的操作,他们不访问他们的属性。

我喜欢我的对象在构造函数中尽可能多地进行初始化并且具有最少数量的mutator。

偏爱不可变对象是明智的选择。 但是bean的好处是框架/工具/库可以在运行时确定类的属性,而不需要您实现特定的接口。

例如,假设您有一个Person bean的集合,并且每个bean都具有名称,年龄,身高等属性。

您可以使用以下代码按名称(例如)对此Bean集合进行排序:

Collection myCollection = // initialise and populate the collection Comparator nameCompare = new BeanComparator("name"); Collections.sort(myCollection, nameCompare); 

BeanComparator类知道如何从每个对象中提取“name”属性,因为遵循Java Beans约定,即您没有实现接口的“开销”,例如:

 interface Nameable { public String getName(); public void setName(String name); } 

Spring MVC的另一个例子是存储请求URL参数的bean。 这可以在Web控制器中定义(在Struts中称为“Action”),如下所示:

 public ModelAndView searchUsers(UserSearchCriteria criteria) { // implementation omitted } 

因为UserSearchCriteria应该是一个JavaBean,如果请求URL包含一个参数,例如maxItems=6 ,那么Spring框架’知道’它应该使用签名调用一个方法

 void setMaxItems(int maxItems); 

本质上,JavaBeans只是一个简单的约定,它允许在运行时(通常通过工具或框架)动态发现类的属性,此时不方便/不可能事先知道可能提供的属性。

我认为最小化可变性是一件好事。 正如已经指出的那样,JavaBeans的优势在于它们很容易被框架处理。

为了充分利用“两个世界”,我认为一个很好的选择是使用Builder模式 ,稍微修改Builder以符合JavaBeans标准。 因此,如果您需要一个框架function,要求您的类符合JavaBeans标准,那么您可以使用Builder而不是实际的类。

当你听到“豆”这个词时,期望看到某种“容器”。 任何类型的JavaBean的想法是为可以在运行时添加和操作的组件提供统一的接口约定。 简单的JavaBeans只是最简单的例子:它提供了所有的接口可能性,并且是Serializable,这意味着您可以创建bean的实例,修改它们,保存它们并重新加载它们。

很久很久以前,我编写了一个Java编辑器,其中包含一个表示文本字符串的简单“数据库”,并且有一个使用bean的“插件架构”。 您可以通过将bean拖出bean存储仓并将其放在编辑器上来向编辑器添加行为; 一旦你这样做,行为(比如,在光标处转置字符的Cntl-T)在编辑器中自动可用。 bean有一个已知的接口—他们知道如何向容器询问其数据结构,以及doSomething()方法—并且容器知道动态加载类文件,实例化对象并设置其访问权限数据库。

顺便说一句,访问者违反封装并不一定是真的; 然而,仅仅因为你有一个成员,你就不需要为它提供get和set方法。 JavaBean规范有点不清楚; 关键是为那些需要在对象“契约”中提供的东西提供getter和setter。

在对语言进行了内省和反思并真正理解之后,对这些公约的需求有所减少; 在早期的Java中,您需要有一个约定来查找方法。

Bean的配置方式使自动化工具可以创建和修改Bean。 它们并不一定是伟大的设计模式。

这些工具的示例:

过冬
JMX