编码系统值的最佳实践

时间:2013-09-18 16:54:58

标签: enums domain-driven-design database-schema

我认为这应该是一个简单的,但没有找到任何明确的答案,最佳做法是什么。

在应用程序中,我们保持订单的当前状态(打开,取消,发货,关闭......)。 如果没有代码更改,此变量不能更改,但应用程序应满足以下条件:

  1. 状态名称应该可以用不同的语言轻松显示,
  2. 应用程序可以通过freetext状态名称进行搜索(例如google搜索“open”)
  3. status_id应该可以通过enum
  4. 提供给开发人员
  5. 添加新状态时零头痛
  6. 到目前为止,我们已经解决了这个问题:

    1. 具有PK(id,language_id)的DB表状态和表示应用程序中此状态的单独枚举。 PROS: 1.,2.,3。开箱即用, CONS: 4.需要在每个客户端安装上运行更新脚本,在处理大量代码表时SQL选择会变得庞大而繁琐
    2. 刚刚枚举: PROS: 3.,4。 缺点: 1.,2。是一场彻头彻尾的噩梦
    3. 有枚举,在应用程序的每个开头填充数据库表: PROS: 1.,2.,3.,4。工作 CONS:应用程序启动时的一些开销,在处理大量代码表时,SQL select会变得庞大而繁琐。
    4. 解决此问题的最常见方法是什么?

4 个答案:

答案 0 :(得分:0)

我愿意并且确实使用方法3,因为它是最好的。您可以使用资源文件存储转换,并将枚举值映射到资源文件中的键。您的数据库可以包含状态的枚举ID。

答案 1 :(得分:0)

听起来你自己总结得很好,并将优点/缺点比作#3。实施#3时只需注释一个:

使用缓存机制(甚至是简单的HashMap!)并添加刷新缓存的选项 - 当您想要更改值时(无需每次都重新启动!),这将简化您的工作。

答案 2 :(得分:0)

1.status名称应该能够以不同的语言轻松显示, 2.application可以通过freetext状态名称搜索(比如google搜索“open”)

这些是接口层的关注点,最好不要在域模型中混用它们。

我会设置状态枚举和i18n代码之间的映射。映射可以存储在文件中(缓存在内存中)或硬编码。

例如:如果您使用dto或查看adatper来渲染您的ui。

public class OrderDetailViewAdapter {
     private Order order;

     public String getStatus() {
         return i18nMapper.to(order.getStatus());//use hardcoded switch case or file impl
     }
}

或者你可以在填充dtos之前完成这个。

您可以为goal2使用类似的解决方案。当用户键入文本时,从映射中找到相应的枚举,并使用枚举进行搜索。

无论如何,使用db表越少越好。

答案 3 :(得分:0)

就个人而言,我总是在域内使用专用的枚举类。此类的责任仅包括状态名称(OPEN,CANCELED,SHIPPED,...)。状态名称在代码库外部不可见。此外,状态也可以作为字符串(varchar或类似)存储在数据库字段中。

出于渲染的目的,根据用例数量,有时我在格式化程序中实现格式化(例如OrderFormatter :: formatStatusName(),OrderFormatter :: formatAbbreviatedStatusName(),...)。如果经常需要格式化,我创建了需要所有格式样式的专用类(OrderStatusFormatter :: short(),OrderStatusFormatter :: abbriviated()...)。当然,需要内部映射来将状态名称映射到状态标题,这是棘手的部分。但是如果你想要分层,就无法避免映射。

到目前为止还没有处理翻译。我在模板中翻译字符串,因此格式化程序不负责任。总结一下:

  1. 域模型中的枚举
  2. 表示层内的格式化程序
  3. 模板内的翻译
  4. 无需为订单状态转换创建特殊表。更好的选择是实现与业务代码分离的通用翻译机制。