【问题标题】:Dealing with enums in a multi-application environment在多应用程序环境中处理枚举
【发布时间】:2011-10-28 08:30:50
【问题描述】:

我们公司主要使用 Java 开发并支持许多“实时”系统(主要是长时间运行的服务器进程),所有这些都依赖于共享参考数据和枚举。有时枚举定义会扩展为包含一个新值,在这种情况下,我们当前重新部署所有应用程序,当这种情况发生时,原因是我们的应用程序每个都有一个包含所有库 jar 的私有“lib”文件夹(包括“枚举实体”库)。显然这是不可取的,所以我很想听听其他人的建议或方法。

我的想法:

  1. 修改每个应用程序的启动脚本以派生最新的“枚举实体”库版本并将 jar 文件添加到类路径。
  2. 在运行时动态类加载新枚举定义的某种机制。

这些方法的问题在于应用程序通常具有以下格式的代码:

switch(enumVal) {
  case A:
    // Do something.
    break;
  case B:
    // Do something.
    break;
  default:
    throw new IllegalArgumentException("Invalid enum value: " + enumVal);
}

... 因此当他们遇到默认情况时将开始失败。也许这表明这些实体根本不应该是枚举;在我们的案例中,这确实是一种方便的权衡。或者它只是表明我们的应用太脆弱了,应该更优雅地处理默认情况。

【问题讨论】:

  • 我认为你必须重新考虑你的应用程序设计。请记住:封装变化的内容。
  • 当枚举定义扩展时,您的所有应用程序是否立即开始使用新值?你用这些枚举做什么?如果您向枚举添加新值,但未在应用程序代码中的任何位置引用它,它是否仍被应用程序使用(例如通过使用 valueOf())?
  • 枚举是编译时常量。所以重启是不够的。如果您更改枚举中的任何内容,则必须重新编译所有使用它们的类。
  • @Udo Fholl:不完全正确,因为 Java 在运行时执行(后期)绑定并且仅按名称执行。如果只向任何类文件(的可见界面)添加新元素,则无需重新编译现有代码。

标签: java enums enumeration


【解决方案1】:

先生。史密斯是对的:扩展枚举,或老派的“枚举” int 常量,很难做到正确,通常不是一个好方法。
正如您所暗示的,新的枚举值需要使用它们的客户端进行特殊的行为/处理。修改枚举后,您也必须修改客户端。这真的很糟糕,你真的应该尝试以另一种方式重新设计它。

【讨论】:

  • 是的,但即使枚举也可以有方法。您被困在单级继承层次结构中,但它们的行为几乎与常规类相同。您也可以对每个枚举常量方法进行不同的覆盖。因此,不要编写开关或 if-else 代码,而是将要完成的事情移到每个枚举/类方法中,然后从客户端代码中调用它。
  • 我再次同意,并且可以补充:如果专门的行为/处理可以在一个地方实现,在枚举本身中,这样对于 所有客户端,它应该首先在客户端中实现。
  • 哦,注意枚举不支持继承,因此不支持多态性。
  • 枚举常量是枚举“类”的一种子类。您可以拥有一个常量特定的类主体,以覆盖在枚举中为某个枚举常量定义的方法。这不是我所说的简洁设计,但它确实有效。
  • 没错,但是客户不能派生他们自己的提供的枚举类型的实现来改变行为。
【解决方案2】:

面向对象是专门为解决这个问题而发明的:你的交换机实际上只是一个显式的虚拟表,而隐式的虚拟表会好得多。您应该考虑重新设计您的应用程序以使用接口/基类而不是枚举。

这将问题转移到对象创建时间,这为每个枚举提供了单个更改点的直接优势。 In 还为引入基于插件的架构开辟了道路,这种架构可能不需要任何重新编译,甚至可能导致在不重新启动应用程序的情况下扩展应用程序的可能性。鉴于您谈到长时间运行的服务器进程,减少停机时间可能很有吸引力。

避免重新编译的最简单方法可能是采用Dependency Injection。使用 Spring 这样的框架,您可以拥有一个或多个配置文件,您可以在其中指定需要创建的对象,然后可以按名称加载它们。

【讨论】:

  • 这很有趣。让我们想象一下他有一个适当的 OO 设计。总有一天,会引入新的要求,并且必须(至少)添加一个新类。有什么替代方法可以在不重新编译的情况下将其放入系统中?
  • 好的,所以现在我们有一个 XML,而不是编码工厂。但是同样,应该在系统中引入新的类,以便 DI 框架实例化它,不是吗?不重新编译怎么办?只是在某个文件夹中添加类文件?还有一个问题:DI 框架是否检测到 XML 已更改,或者需要重新启动?
  • 是的,您可以将类文件添加到文件夹或 jar 中,尽管后者可能会阻止“热”添加。我不熟悉如何自动升级配置的细节,因为我自己从来不需要这样做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-04
  • 2019-10-25
相关资源
最近更新 更多