我想知道我是否遗漏了一些关于Java Bean的东西。我喜欢我的对象在构造函数中尽可能多地进行初始化,并且具有最少数量的mutator。豆似乎直接反对这一点,并且通常感到笨重。我没有将我的对象构建为Beans而错过了哪些功能?
答案 0 :(得分:13)
听起来你走在正确的轨道上。不是你错过了Java Beans的观点,而是其他程序员滥用它们。
Java Beans规范旨在与可视化工具一起使用。我们的想法是,应用程序设计人员能够以交互方式配置对象的实例,然后对配置的bean进行序列化(或生成代码),以便可以在运行时重构它;意图是它不会在运行时发生变异。
不幸的是,很多开发人员都不理解accessors violate encapsulation。他们使用结构而不是对象。他们没有看到其他类,甚至其他包有任何错误,依赖于类的数据成员。
当然,您通常需要配置对象的实例。只是应该通过某种配置功能来完成。这可能是依赖注入容器,“BeanBox”样式可视化工具,或者只是读取您手动编写的JSON,XML或属性文件。关键是在运行时这些对象实际上是不可变的;客户只是调用他们的操作,他们不访问他们的属性。
答案 1 :(得分:7)
我喜欢我的物品 在构造函数中初始化为 可能并且具有最小数量 存取器。
支持不可变对象是明智的选择。但是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中称为“Action”),如下所示:
public ModelAndView searchUsers(UserSearchCriteria criteria) {
// implementation omitted
}
因为期望UserSearchCriteria是JavaBean,如果请求URL包含maxItems=6
之类的参数,则Spring框架“知道”应该使用签名调用方法
void setMaxItems(int maxItems);
实质上,JavaBeans只是一个简单的约定,它允许在运行时(通常通过工具或框架)动态发现类的属性,此时不方便/不可能事先知道可能提供的属性。
答案 2 :(得分:3)
我认为最小化可变性是一件好事。正如已经指出的那样,JavaBeans的优势在于它们很容易被框架处理。
为了充分利用“两个世界”,我认为一个好的选择是使用Builder pattern,稍微修改Builder以符合JavaBeans标准。因此,如果您需要一个框架功能,要求您的类符合JavaBeans标准,那么您可以使用Builder而不是实际的类。
答案 3 :(得分:2)
当你听到“bean”这个词时,期望看到某种“容器”。任何类型的JavaBean的想法是为可以在运行时添加和操作的组件提供统一的接口约定。简单的JavaBeans只是最简单的例子:它提供了所有的接口可能性,并且是Serializable,这意味着您可以创建bean的实例,修改它们,保存它们并重新加载它们。
很久很久以前,我编写了一个Java编辑器,其中包含一个表示文本字符串的简单“数据库”,并且有一个使用bean的“插件架构”。您可以通过将bean拖出bean存储仓并将其放在编辑器上来向编辑器添加行为;一旦你这样做,行为(比如,Cntl-T转换光标处的字符)在编辑器中自动可用。 bean有一个已知的接口---他们知道如何向容器询问其数据结构和doSomething()方法---并且容器知道动态加载类文件,实例化对象并设置其访问权限数据库。
顺便说一下,访问者违反封装并不一定是真的;然而,仅仅因为你有一个成员,你就不会需要来为它提供get和set方法。 JavaBean规范有点不清楚;关键是为那些需要在对象“契约”中提供的东西提供getter和setter。
在对语言进行了内省和反思并真正理解之后,对这些公约的需求有所减少;在早期的Java中,你需要有一个约定来找到这些方法。
答案 4 :(得分:1)