2

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

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

  1. 状态名称应该很容易以不同的语言显示,
  2. 应用程序可以通过自由文本状态名称搜索(如谷歌搜索“打开”)
  3. status_id 应该通过枚举提供给开发人员
  4. 添加新状态时零头痛

到目前为止,我们已经解决了这个问题的可能方法:

  1. 具有带有 PK(id, language_id) 的 DB 表状态和一个表示应用程序中此状态的单独枚举。 优点: 1.,2.,3。开箱即用,缺点: 4. 需要在每个客户端安装上运行更新脚本,当处理大量代码表时,SQL 选择会变得大而繁琐
  2. 只有枚举: 优点: 3.,4。缺点: 1.,2。是一场噩梦
  3. 具有枚举,在每次启动应用程序时填充数据库表: 优点: 1.,2.,3.,4。工作缺点:在处理大量代码表时,应用程序启动时会产生一些开销,SQL 选择会变得庞大而繁琐。

解决此问题的最常见方法是什么?

4

4 回答 4

0

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

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

目前还没有翻译。我在模板中翻译字符串,这样格式化程序就不用负责了。总结一下:

  1. 域模型内的枚举
  2. 表示层内的格式化程序
  3. 模板内翻译

无需为订单状态转换创建特殊表。更好的选择是实现与您的业务代码分开的通用翻译机制。

于 2013-09-21T13:10:29.290 回答
0

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

于 2013-09-18T16:59:53.930 回答
0

1.状态名称应该很容易以不同的语言显示,2.应用程序可以通过自由文本状态名称搜索(如谷歌搜索“打开”)

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

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

例如:如果您使用 dto 或 view adatper 来呈现您的 ui。

public class OrderDetailViewAdapter {
     private Order order;

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

或者,您可以在填充 dto 之前完成此操作。

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

无论如何,使用数据库表越少越好。

于 2013-09-19T01:10:41.743 回答
0

听起来您自己总结得很好,并将优缺点与#3进行了比较。但是,当您实施 #3 时,只有一条评论:

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

于 2013-09-18T17:09:30.757 回答