枚举值命名为

时间:2017-09-29 10:12:56

标签: java enums naming-conventions naming

我是一名Java开发人员,试图掌握最好的清洁代码实践。今天,我和我的同事讨论了枚举命名问题。请分享您对此主题的看法。

我所相信的是,枚举值的名称应该是Java代码的一部分,并且与代码库保持一致。名称,必须是可理解的,并且与它所代表的内容相关。它必须以各种可能的方式将值与1:1映射...但是名称,不一定是值。

所以,我们假设我们有一组给定的可怕命名列:

  • grapescountscolumnofinttype

  • secondlongernameofdoubletype

  • someveryfunkycolumnamewithsomeannotation。

如果我们要创建一个枚举“ColumnNames”,我对干净代码的想法是让它们尽可能可读,所以:

  • GRAPES_COUNT

  • 第二

  • 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 个答案:

答案 0 :(得分:0)

  

我所相信的是,enum值' name,应该是Java代码的一部分,并与代码库保持一致。名称,必须是可理解的,并且与它所代表的内容相关。它必须以各种可能的方式将值与1:1进行映射

(1)我同意这一点。

  

但名称,不一定是有价值的。

(2)我认为这也是事实。可以从以下事实推断出这一点:您可以使用int s或不是有效java名称的字符串作为枚举值。所以,这种说法是正确的,除非java语言不符合它的意图,我不认为这就是这种情况。

  

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

     

[...]

     

并将实际列名保持为"值"

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

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

(B)如果您对此枚举的意图是您的核心业务模型的一部分,这是一个坏主意,因为对数据库模式的隐含依赖使您的核心模型依赖于它(除非这个数据库模式是业务模型设计的固有部分,这是可能的,但可能不是这里的情况。)

  

据我的同事说,如果我们枚举列,那么名称应该与列名匹配。

我不同意这一点,因为(1),无论(A)或(B)是否属实。

  

否则,我们不会枚举列,而是映射到列/从列中映射的内容,然后不应将枚举命名为" TableColumns"。

如果(A)是真的,我会同意这一点,而且我同意简单地说" TableColumns"在这里没有充分反映意图和影响。原因是没有表达对特定数据库模式/表的隐式依赖(映射)。但是,如果将该枚举放在适当的命名空间(包)中,如com.appname.schemaname.tablename.TableColumns或简称com.appname.db.tablename.TableColumns,这就足够了。这样,隐式依赖关系在包结构中明确表示,如果您尝试将其用作业务模型的一部分,则更加明显和警示。

如果(B)成立,我也同意,但在这种情况下,命名并不是真正的问题,对数据库模式的隐藏依赖是。

  

对于命名枚举的最佳,最干净的方法有什么想法?

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

  • 使用已建立的java标识符命名约定,不要将特定内容(如文字特定的数据库名称)泄露到标识符中(参见(1))
  • 可以使用enum作为一组封闭的常量,也可以作为一组" mappers"。这是一个功能,而不是滥用(见(2))。请注意,这可能会引入一些隐式依赖项
  • 使用命名来支持核心业务模型和细节之间的区别(或者,通常,应该控制彼此依赖的任何上下文),命名空间对此有很好的帮助

答案 1 :(得分:0)

因此,随着JDK 6中枚举的更改,尚未应用所应用的命名标准,因此您阅读或使用的所有内容都将假定为标准JDK 1.5静态命名。仅强调和大写。这包括鱿鱼参考和其他。 这是公认的答案。

但是我发现/感觉根本不是这种情况,自JDK 6起,基本静态类型和复杂枚举类型之间必须有明确和明确的分隔,我使用命名约定来强调这一点。

用于枚举的骆驼保护套。

private static final String BASIC_STATIC_TYPE;

enum EnumType
{
One,Two,Three,Four("OptionalChange");

public String toString()
{
return data == null ? name() : data;
}
}

这允许正确的突出显示和语法处理,并立即告诉开发人员这不是原始类型(静态最终),而是具有原始指针的MetaSpace中的对象引用。 代码变得更加简洁,而不必研究静态类型来查找任何方法/如果它是基本原语。

这是我不会感到不舒服就打破的一条基本规则。我想通过查看名称而不是通过检查引用来了解static和枚举之间的区别。

使用具有数字引用的枚举,我在前面加上$