7

我不太了解 Java Beans 的本质。好吧,至少我是如何看待它们在通过我们商店的一些代码库中使用的。

我发现了这个问题:

Java Beans:我错过了什么?

那里接受的答案看起来像是程序员倾向于滥用Java Bean(我真的不怀疑),但我看到它经常如此故意地发生,我认为我仍然错过了一些东西。

我看到的代码如下:

public class FooBean {
  private int a;
  private int b;
  private int c;

  public int getA() { return a; }
  public int setA(int x) { a = x; }

  // etc...
}

没有比 getter 和 setter 更进一步的结构或控制。是否存在某种超级棒的编译器技巧,涉及反射、getter 和 setter,以及需要一些非常笨拙(但编译器优化)的静态关联数组?

或者,也许我完全没有抓住重点。:\

干杯!

编辑:

绝对不是在这里宣传公共领域的想法。

4

6 回答 6

8

事实上,是的,魔法正在发生。

这是一个非常愚蠢的模式,但 GUI bean(所有组件都是)旨在由 GUI 构建器进行反射分析。公共设置/获取字段旨在成为用户在构建其 GUI 时可以使用的“属性”。

编辑:为太阳辩护,我应该说虽然这种模式被证明是非常令人讨厌的,因为所有的人都复制了它并开始在他们的非 bean 代码中使用它,但它确实允许人们将类与 GUI 构建器集成不使用任何外部元数据。编辑器不需要任何 XML 文件或属性文件,它就像扩展 Button 并将新对象放到托盘上一样简单。

这种模式已在其他地方使用过,正如您所注意到的,它与拥有公共字段几乎相同。我认为这是 sun 在设置 java 时创建的最糟糕的模式之一,但没有其他明显的解决方案(我认为整个概念是在 java 发布之前尝试构建第一个 GUI 构建器的第一批人所采用的)。

现在有一个更好的解决方案:使用注释标记私有字段,反射工具仍然可以分析它们并将它们绑定到构建器控件。这将是一个很好的清洁,并且不会使您的所有对象都容易受到外部状态更改的影响。

于 2009-07-27T17:15:52.190 回答
3

Java Beans are, as you point out, a fairly trivial coding convention.

The useful part is that they were a convention at all. This allowed auxiliary tools to be built which were based on (at the time) novel ideas like specifying exactly what the name of getters and setters were, and an expectation that specific methods would exist without needing to ascribe to an Interface. This allowed enough flexibility to do whatever you wanted, but still allowed you to use the GUI for assembling beans.

At this point, with full introspection being the norm, and other languages having formalized get/set functionality, and many other ways to do what Beans do, I think they're an idea whose time has passed.

于 2009-07-27T17:23:30.960 回答
2

人们确实过度使用愚蠢的 getter/setter,这一点毫无疑问。

setEmail(string email);但是,想象一下,当您意识到必须从方法中的字符串中去除空格并且您的所有代码都硬耦合以使用公共字段而不是方法调用时,您必须经历 2 年的痛苦。

记住面向对象设计的主要规则之一“面向接口而不是实现的代码”。访问类的公共字段肯定是后者,并且会使重构代码更加困难。

于 2009-07-27T17:03:06.943 回答
1

你没有错过重点。Getter/Setter 很丑陋,但被嵌入到如此多的工具中,这些工具对类/方法/字段名称(例如 spring)做出假设(除了它们明显的封装价值之外)它们实际上已成为近乎要求,除非你是在非常有限和私人的环境中工作。

于 2009-07-27T18:12:27.163 回答
0

如果您想覆盖对数据的访问,例如用于日志记录/安全性或返回与原始类不同的值,则“getters”和“setters”非常有用。

于 2009-07-27T17:02:27.973 回答
0

没有设置器,您将无法检查不变量:

public void setFoo(Foo foo) { 
     if (foo == null) {
          throw new InvalidFoo();
     }

     this.foo = foo;
}

对于公共成员,您不能这样做。第二点,在 setter 中,您可以触发其他 bean 可以侦听的事件。最后但并非最不重要的一点是,您可以强制执行正确的类型检查(正如您在问题中指出的那样)。

于 2009-07-27T17:13:41.040 回答