有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java枚举值命名

我是一名Java开发人员,试图掌握最佳的干净代码实践。今天,我和同事就枚举命名问题发生了争论。请分享你对这个话题的看法

我认为,枚举值的名称应该是Java代码的一部分,并与代码库保持一致。名称,必须是可以理解的,并与它所代表的意义切中要害。它必须以1:1的比例以各种可能的方式映射这些值。。。但名称不一定是值

那么,让我们假设我们有一组给定的名称可怕的列:

  • GrapeCountsColumnOfInType

  • 第二个长时间的双重模式

  • 有些未知的列名称带有注释

如果我们要制作一个枚举“ColumnNames”,我对干净代码的想法是让它们尽可能可读,因此:

  • 葡萄计数

  • 第二

  • VERFY_FUNKY

并将真正的列名保留为“值”(与this.getColumnName()或其他任何内容一起使用)

据我的同事说,如果我们要枚举列,那么名称应该与列名匹配。否则,我们不枚举列,而是映射到列或从列中映射的内容,然后枚举不应命名为“TableColumns”

有没有想过什么是命名枚举的最好、最干净的方法

@Edit:添加示例代码

非常丑陋的SQL:

create table table ( grapescountscolumnofinttype number not null,
  secondlongernameofdoubletype number not null,
  someveryfunkycolumnamewithsomeannotation number not null);

转换为干净的Java代码:

private enum TableColumn {
  GRAPESCOUNTSCOLUMNOFINTTYPE,
  SECONDLONGERNAMEOFDOUBLETYPE,       
  SOMEVERYFUNKYCOLUMNAMEWITHSOMEANNOTATION 
}

vs

private enum TableColumn {
  GRAPES_COUNTS("grapescountscolumnofinttype"),
  SECOND("secondlongernameofdoubletype"),
  VERY_FUNKY("someveryfunkycolumnamewithsomeannotation")
...

private String value;
  String getColumnName() { 
    return value;
  } 
}

共 (2) 个答案

  1. # 1 楼答案

    因此,随着JDK 6中枚举的更改,应用的命名标准没有更新,您阅读或遇到的所有内容都将采用标准JDK 1.5静态命名。只有下划线和大写字母。这包括squid参考和其他内容。 这是公认的答案

    但我发现/感觉情况并非如此,自JDK 6以来,基本静态类型和复杂枚举类型之间需要有一个明确而明确的分离,我使用命名约定来强调这一点

    枚举的骆驼案例

    private static final String BASIC_STATIC_TYPE;
    
    enum EnumType
    {
    One,Two,Three,Four("OptionalChange");
    
    public String toString()
    {
    return data == null ? name() : data;
    }
    }
    

    这允许正确的高亮显示和语法处理,并立即告诉开发人员这不是一个基元类型(静态韵母),而是元空间中带有基元指针的对象引用。 代码变得更干净,无需调查静态类型以找到任何方法/如果它是基本原语

    这是一条基本规则,我会打破它而不感到任何不适。我想通过查看名称而不是检查引用来了解静态和枚举之间的区别

    使用带有数字引用的枚举,我在前缀中加了一个$

  2. # 2 楼答案

    What I belive, is that the enum values' name, should be a parto of the Java code and stay consistent with the code base. Name, has to be understandable and to-the-point with what it does represent. It has to map 1:1 with the values in every possible way

    我同意这一点

    BUT the name, does not have to be value.

    我认为这也是事实。可以从以下事实推断出这一点:对于枚举的值,可以使用int或不是有效java名称的字符串。所以,这句话是正确的,除非java语言与它的意图不一致,我认为这里的情况并非如此

    If we'll make an enum "ColumnNames", my idea of clean code is to make those as readable as possible

    [...]

    And keep the real column name as the "value"

    这是一个有趣的部分,可以用多种方式来解释

    (A)从设计的角度来看,如果您的目的是使这个枚举成为java代码和数据库模式之间映射的表达式,那么这是一个好主意。这意味着特定的java代码段和该db模式之间存在依赖关系

    (B)如果您打算将此枚举作为核心业务模型的一部分,这是一个坏主意,因为对db模式的隐含依赖使您的核心模型依赖于它(除非此db模式是设计业务模型的固有部分,这是可能的,但这里可能不是这样)

    According to my colleague, if we are enumerating the columns, then the name should match the column name.

    因为(1),无论(A)或(B)是真的,我都不会同意

    Otherwise, we are not enumerating the columns, but something that is mapped to/from the columns, and then the enum should not be named "TableColumns".

    如果(A)是真的,我会同意这一点,而且我也会同意简单的“TableColumns”并不能很好地反映本文的意图和含义。原因是没有表达到特定db模式/表的隐式依赖关系(映射)。但是,如果您将该枚举放在适当的名称空间(包)中,比如com.appname.schemaname.tablename.TableColumns或简单地com.appname.db.tablename.TableColumns,这就足够了。通过这种方式,隐式依赖关系在包结构中被显式表达,如果您试图将其作为业务模型的一部分使用,它会更加明显和令人担忧

    如果(B)是真的,我也会同意,但在这种情况下,命名并不是一个真正的问题,而是对db模式的隐藏依赖

    Any thoughts on what is the best, cleanest way of naming enums?

    总结我上面所说的,我建议:

    • 对java标识符使用已建立的命名约定,不要在标识符中泄露细节(如特定于文字的db名称)(请参见(1))
    • 使用枚举不仅可以作为一组闭合的常量,还可以作为一组“映射器”。这是一个特性,而不是滥用(见(2))。请注意,这可能会引入一些隐式依赖关系
    • 使用命名来支持核心业务模型和细节之间的区别(或者,一般来说,任何相互依赖的上下文都应该受到控制),名称空间在这方面很有帮助