代码之家  ›  专栏  ›  技术社区  ›  Jeremy Powell

Java bean:过度修饰的关联数组?

  •  6
  • Jeremy Powell  · 技术社区  · 15 年前

    我不太理解Java bean的本质。好吧,至少我看到它们在一些代码库中的使用,这些代码库通过我们的商店。

    我发现这个问题:

    Java Beans: What am I missing?

    那里的被接受的答案使程序员看起来容易滥用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,以及需要一些非常笨拙(但经过编译器优化)的静态关联数组?

    或许我是 完全地 错过了要点。:

    干杯!

    编辑:

    这里绝对不会宣传公共领域的理念。

    6 回复  |  直到 15 年前
        1
  •  8
  •   Bill K    15 年前

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

    这是一个非常愚蠢的模式,但是GUI bean(所有组件都是)被一个GUI构建器反射性地分析。公共集合/获取字段旨在成为用户在构建GUI时可以处理的“属性”。

    编辑:为了保护Sun,我应该说,尽管模式因为所有复制它并开始在非bean代码中使用它的人而变得非常讨厌,但它确实允许人们在不使用任何外部元数据的情况下将类与GUI生成器集成。编辑器不需要任何XML文件或属性文件,只需扩展按钮并将新对象放到托盘上即可。

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

    现在有了一个更好的解决方案:使用注释标记私有字段,反射工具仍然可以分析它们并将它们绑定到生成器控件。这将是一个非常干净的方法,并且不会使所有对象都如此容易受到外部状态更改的影响。

        2
  •  3
  •   Alex Feinman    15 年前

    正如你所指出的,JavaBean是一个相当琐碎的编码约定。

    有用的部分是,它们完全是一种惯例。这使得辅助工具可以建立在(当时)新颖的思想基础上,比如精确地指定getter和setter的名称,以及期望特定的方法可以存在而不需要归因于接口。这允许足够的灵活性来做您想要做的任何事情,但仍然允许您使用GUI来组装bean。

    在这一点上,随着全面的自省成为标准,其他语言具有形式化的获取/设置功能,以及许多其他方式来完成bean所做的工作,我认为它们是一个时间已经过去的想法。

        3
  •  2
  •   skaffman    15 年前

    毫无疑问,人们会过度使用愚蠢的getter/setter。

    然而,想象一下当你意识到 你必须脱掉你身上的绳子 setEmail(string email); 方法和所有代码都是硬耦合的,无法使用公共字段而不是方法调用。

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

        4
  •  1
  •   Steve B.    15 年前

    你没有错过要点。getter/setter很难看,但是嵌入到许多工具中,这些工具对类/方法/字段名(例如spring)进行假设,使它们(除了封装的明显价值外)实际上成为了一个接近需求,除非您在 非常 有限的私人背景。

        5
  •  0
  •   Pierre    15 年前

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

        6
  •  0
  •   dfa    15 年前

    如果没有setter,则无法检查不变量:

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

    对于公众成员,你不能这样做。第二点,在setter中,您可以触发其他bean可以监听的事件。最后,您可以执行适当的类型检查(正如您在问题中指出的那样)。