当前位置: 首页 > 面试题库 >

使用和保留枚举的最佳实践

诸葛康胜
2023-03-14
问题内容

我在这里看到了一些有关处理和持久保存枚举式值的最佳方法的问题/讨论(例如,持久化适用于枚举的数据,如何使用NHibernate来持久化枚举),我想问一下一般共识是什么。

特别是:

  • 这些值应如何在代码中处理?
  • 应该如何将它们持久保存到数据库中(作为文本/作为数字)?
  • 不同解决方案的权衡是什么?

注意:我已将本问题中最初包含的解释移至答案。


问题答案:

我试图总结我的理解。 如果有任何更正,请随时进行编辑。因此,它去了:

在代码中

在代码中,应该使用语言的本机枚举类型(至少在Java和C#中)或使用诸如“typesafe枚举模式”之类的枚举来处理枚举。不推荐使用普通常量(整数或类似常量),因为这样会丢失类型安全性(并使您难以理解哪些值是合法输入的值,例如方法)。

两者之间的选择取决于要附加给枚举的附加功能:

  • 如果要将大量的功能放入枚举(这很好,因为可以避免一直在其上进行switch()操作),通常使用一个类更为合适。
  • 另一方面,对于简单的枚举式值,语言的枚举通常更清晰。

特别是,至少在Java中,一个枚举不能从另一个类继承,因此,如果有多个具有相似行为的枚举要放入超类中,则不能使用Java的枚举。

持久枚举

若要持久枚举,应为每个枚举值分配一个唯一的ID。可以是整数,也可以是短字符串。首选短字符串,因为它可以助记(使DBA等更容易理解db中的原始数据)。

  • 在软件中,每个枚举都应具有映射功能,以在枚举(供软件内部使用)和ID值(用于持久化)之间转换。一些框架(例如(N)Hibernate)具有自动执行此操作的有限支持。否则,您必须将其放入枚举类型/类。
  • 该数据库应该(理想情况下)包含每个表的列表,其中列出了合法值。一列是ID(请参见上文),即PK。其他列可能对例如描述有意义。然后,将包含该枚举中的值的所有表列都可以将此“枚举表”用作FK。这样可以确保永远不会保留错误的枚举值,并允许数据库“独立”。

这种方法的一个问题是合法枚举值的列表存在于两个位置(代码和数据库)。这很难避免,因此通常被认为可以接受,但是有两种选择:

  • 仅将值列表保留在数据库中,在构建时生成枚举类型。优雅,但意味着运行构建需要数据库连接,这似乎是有问题的。
  • 将代码中的值列表定义为具有权威性。在运行时(通常在启动时)检查数据库中的值,不匹配时投诉/中止。


 类似资料:
  • 问题内容: 有没有办法使用NHibernate将枚举持久化到数据库?那有一张代码表和枚举中每个值的名称。 我想保留没有实体的枚举,但仍然具有从所有其他引用实体到枚举的表的外键(枚举的int表示形式)。 问题答案: 你们为什么把这个复杂化呢?真的很简单。 映射如下所示: 该模型属性如下所示: 枚举看起来像这样: NHibernate将自动解决所有问题。为什么键入比您需要的更多???

  • 问题内容: 枚举大小写是否可以使用保留关键字? 例如: 在其他语言中,这可以通过以某种方式转义关键字来实现,例如在scala中,我们使用反引号,例如 尽管是保留关键字,但仍可以用作标识符。 迅速有类似的东西吗? 问题答案: 从《 Swift语言指南》(“ 命名常量和变量”部分) 如果需要为常量或变量提供与保留的Swift关键字相同的名称,则在使用该关键字作为名称时,请在关键字前后加上反斜线(`)。

  • 问题内容: 我们有一个REST API,客户端可以在其中提供代表Java Enums中服务器上定义的值的参数。 因此,我们可以提供一个描述性错误,我们将此方法添加到每个Enum中。似乎我们只是在复制代码(错误)。有更好的做法吗? 更新 :提供的默认错误消息为。我想提供一个来自API的更具描述性的错误。 问题答案: 可能可以实现通用静态方法。 像这样 那么你就可以 或显式调用实用程序类查找方法。

  • 问题内容: 大多数项目的某些数据在版本之间基本上是静态的,并且非常适合用作枚举,例如状态,事务类型,错误代码等。例如,我只使用一个通用的状态枚举: 我想知道其他人在处理此类数据方面的持久性。我看到一些选择,每个选择都有明显的优点和缺点: 将可能的状态保留在状态表中,并保留所有可能的状态域对象,以供在整个应用程序中使用 只使用一个枚举,而不保留可用状态列表,这在我和我的DBA之间造成了数据一致性的圣

  • 问题内容: 我读了《有效Java》,其中指出最好使用来实现单例。 此方法在功能上等效于公共领域方法,除了它更简洁,免费提供序列化机制,甚至针对复杂的序列化或反射攻击,还提供了针对多重实例化的明确保证。尽管此方法尚未得到广泛采用,但是单元素枚举类型是实现单例的最佳方法。 尽管如此,这似乎是在动态序列化和真正的单实例上实现的折衷方案,但您却失去了经典单例的更友好的OOP方法。枚举不能被继承,只能实现一

  • 我有一个RESTful Web API项目,我有2个不同的Enum场景,我不确定是最佳实践。 场景1:简单的枚举参数 我的API方法需要一个名为的参数,有效值为和。Web API项目中的枚举如下所示: 我对这个场景的问题是,我应该使用<code>吗?ruleType=EmailAddress(它会自动将该值绑定到API方法中的property)?如果是,如何最好地验证发送的<code>RuleTy