Java Beans:我错过了什么?

2022-09-02 21:11:48

我想知道我是否错过了一些关于Java Beans的东西。我喜欢我的对象在构造函数中做尽可能多的初始化,并且具有最小数量的赋值器。豆类似乎直接与此背道而驰,并且通常感觉笨拙。由于没有将对象构建为 Bean,我错过了哪些功能?


答案 1

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

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

不幸的是,许多开发人员不明白访问器违反了封装。他们使用结构而不是对象。他们没有看到其他类(甚至是其他包)依赖于类的数据成员有什么问题。

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


答案 2

我喜欢我的对象在构造函数中做尽可能多的初始化,并且具有最小数量的赋值器。

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

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

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

Collection<Person> 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中称为“操作”),如下所示:

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

因为UserSearchCriteria应该是一个JavaBean,所以如果请求URL包含一个参数,比如,Spring框架“知道”它应该调用一个带有签名的方法。maxItems=6

void setMaxItems(int maxItems);

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


推荐