代码之家  ›  专栏  ›  技术社区  ›  Konrad Rudolph

Java中getter的命名约定有多重要?

  •  10
  • Konrad Rudolph  · 技术社区  · 16 年前

    我非常相信一致性,因此也相信惯例。

    get / set 前缀约定)似乎妨碍了可读性。例如,一些类将具有 id name 属性和使用 o.getId() 而不是 o.id() 出于多种原因,这似乎毫无意义:

    • 这些类是不可变的,因此(通常)不会有相应的设置器,
    • 没有混淆的机会,
    • 得到
    • 我用这个 得到 -在整个库中,命名模式的一致性较差。

    Collection 类(以及Java平台库中的其他类)也违反了JavaBean约定(例如,它们使用 size 而不是 getSize 等等)。

    从不 因为它们不能以这种方式有意义地使用。

    另一方面,我 我是一位经验丰富的Java用户,我不知道其他Java开发人员对库有什么期望。我可以效仿Java平台类的例子吗?还是说这被认为是一种糟糕的风格?是否违反了 得到 / 回想起来,Java库类中的约定是否被认为是一个错误?或者,当JavaBean约定不适用时,忽略它们是完全正常的吗?

    Sun code conventions for Java 完全不要提及此事。)

    6 回复  |  直到 16 年前
        1
  •  11
  •   Brian Agnew    16 年前

    如果您遵循适当的命名约定,那么第三方工具可以轻松地与您的库集成并使用。他们会期待 getX() , isX() 等等,并试图通过反思找到这些。

    虽然你说这些目前不会作为JavaBeans公开,但我仍然会遵循惯例。谁知道你以后可能想做什么?或者,在稍后的阶段,您可能希望提取此对象的接口,并创建一个可以通过其他工具访问的代理?

        2
  •  6
  •   KLE rslite    16 年前

    我其实讨厌这个惯例

    但我确实遵守这个惯例


    我想提出另一个问题:通常,java软件使用了太多的访问器和修饰符(get/set)。我们应该更多地应用“ 告诉我,不要问

        class A {
          B b;
          String c;
          void a() {
            String c = b.getC();
            String d = b.getD();
            // algorithm with b, c, d
          }
        }
    

        class A {
          B b;
          String c;
          void a() {
            b.a(c); // Class B has the algorithm.
          }
        }
    

    通过这种重构可以获得许多好的属性:

    • B可以是不可变的(非常适合线程安全)
    • 在B中的实现比在A中更简单,因为你不必使用getter和外部访问数据,你在B中,可以利用实现细节(检查错误、特殊情况、使用缓存值……)。
    • 由于位于B中,它具有更多的耦合(两个属性而不是A的一个属性),重构A可能不会影响算法。对于B重构,这可能是改进算法的机会。所以维护更少。
        3
  •  5
  •   JesperE    16 年前

    违反Java库类中的get/set约定肯定是一个错误。我真的会推荐你 为了避免知道为什么/什么时候不遵守惯例的复杂性。

        4
  •  4
  •   gustafc    16 年前

    乔什·布洛赫实际上在这件事上站在你一边 Effective Java get -为了可读性,对于不打算用作bean的东西,要减少变体。当然,并不是每个人都同意布洛赫的观点,但这表明有支持和反对倾销的理由 (我认为它更容易阅读,所以如果YAGNI,抛弃它 得到

    关于 size() 方法来自集合框架;当你看到,比如说,最近的 Enum 类具有 name() ordinal() (这可能可以用布洛赫是其中之一来解释) 的两位作者。 )

        5
  •  2
  •   VonC    16 年前

    get less模式用于scala(和 other languages Uniform Access Principle :

    Scala将字段名和方法名保存在同一个命名空间中,这意味着如果一个方法名为count,我们就无法命名字段count。许多语言,如Java,没有这种限制,因为它们将字段和方法名称保存在单独的名称空间中。

    由于Java不打算为“属性”提供UAP,因此最好使用get/set约定来引用这些属性。

    • Foo.bar Foo.bar()
    • Foo.bar = 5 Foo.bar(5)

    在Java中,您无法实现UAP,因为 Foo.bar Foo.bar() 位于两个不同的命名空间中。
    Foo.bar() ,这与调用任何其他方法没有什么不同。
    因此,这种get-set约定可以帮助将该调用与其他调用(与属性无关)区分开来,因为“模块提供的所有服务(这里“只是读取/设置一个值,或计算它”)都不能通过统一的表示法获得”。

    如果UAP在Java中可用,则根本不需要这种约定。

    注: size() 而不是 getSize() 可能是为了Java的口头禅“向后兼容:始终”而保留的一个遗留的糟糕命名。

        6
  •  0
  •   Esko    16 年前

    如果你不提供这种记录良好、合理的访问器/修改器机制,你的框架/库就无法与大多数其他库/框架一起使用。

    推荐文章