【问题标题】:Logic inside an enum枚举中的逻辑
【发布时间】:2010-03-19 00:07:51
【问题描述】:

我和我的同事正在讨论枚举中的逻辑。我个人的偏好是在 Java 枚举中有任何类型的逻辑(尽管 Java 提供了这样做的能力)。本案例中的讨论集中在枚举内部有一个返回映射的便捷方法:

public enum PackageType {
  Letter("01", "Letter"),
  ..
  ..
  Tube("02", "Packaging Tube");

  private String packageCode;
  private String packageDescription;

  ..
  ..

  public static Map<String, String> toMap() {
     Map<String, String> map = new LinkedHashMap<String, String>();
     for(PackageType packageType : PackageType.values()) {
         map.put(packageType.getPackageCode(), packageType.getPackageDescription());
     }
     return map;
  }
}

我个人的偏好是将其应用到服务中。将方法包含在枚举中的论点以方便为中心。这个想法是您不必去服务获取它,而是可以直接查询枚举。

我的论点集中在关注点分离和将任何类型的逻辑抽象到服务中。我不认为“方便”是将此方法放在枚举中的有力论据。

从最佳实践的角度来看,哪个更好?还是仅仅是个人喜好和代码风格的问题?

【问题讨论】:

  • 如果字符串是最终的,考虑在静态初始化时制作一个不可变的地图,而不是每次有人调用 toMap() 时都滚动一个

标签: java enums


【解决方案1】:

嗯,我以前做过,但这并不意味着这是“最好”的事情。

不过,从我的角度来看,我更愿意在枚举中使用该逻辑,原因与您不会将“toString”方法移到服务中的原因相同。逻辑只涉及枚举本身和它自己的表示。

我认为将这样的方法移到服务中会产生误导——通过将其放在枚举上,您就可以提前了解枚举具有“toMap”方法这一事实。不了解该服务而只是查看枚举的人可能不知道。

它还有助于在 IDE 中自动完成 - 我可以点击“。”键并立即查看对象提供的方法。

【讨论】:

    【解决方案2】:

    我认为这可能取决于个人喜好以及您是否认为未来逻辑可能会改变。

    枚举逻辑的最佳用例(因为它是静态的)用于不会改变的事物。 java.util.concurrent.TimeUnit 中的逻辑就是一个很好的例子:时间单位之间的转换因子是明确定义的并且永远不会改变,因此它是嵌入到枚举中的静态逻辑的一个很好的候选。

    【讨论】:

      【解决方案3】:

      我看不出任何有说服力的理由说明为什么按照你的建议去做是“好的做法”……或“坏的做法”……。

      我倾向于使用方便的说法。但坦率地说,这不是那种花人日辩论有成效的事情 ... IMO。

      【讨论】:

      • 我正要发表评论说'这可能是在午餐时间'
      • 嗯……你的午餐更有趣……IMO :-)
      【解决方案4】:

      我在枚举中尝试过几次逻辑,但我唯一真正高兴的是:

      // not compiled, so might have errors...
      public enum Foo
      {
         A,
         B;
      
         // not complete, doesn't properly handle invalid cases...
         public static Foo fromString(final String str)
         {
             final String strLower;
             final Foo    val;
      
             strLower = str.toLowerCase();
      
             if(strLower.equals("a")
             {
                 val = A;
             }
             else if(strLower.equals("b")
             {
                 val = B;
             }
             else
             {
                 throw new IllegalArgumentException(/*...*/);
             }
      
             return (val);
         }
      }
      

      通常,一旦您开始添加实例变量/方法,您可能应该使用适当的类来做一些事情。

      【讨论】:

        【解决方案5】:

        我先把它放在枚举中。如果系统中只有一个 toMap() 方法,那么有一个额外的类肯定是​​不必要的,而且会很烦人。

        如果我有一堆枚举,我想从中创建这样的地图,或者可能预料到这种情况,那么我将创建一个静态实用程序类和一个通用实用程序方法来做到这一点。

        我个人的看法是,实用性凌驾于理论之上。

        编辑:哦,等等,这将很难提供一个通用的实用方法。在这种情况下,如果该方法将是特定于枚举的,我肯定会把它放在枚举中。如果我是维护程序员,如果你有一个额外的类需要我寻找,我会非常不满意。

        【讨论】:

        • 如果您使用一种策略来确定要放入地图中的内容,这将变得微不足道,但是为另一个接口/类添加对枚举的依赖,这有点滥用。如果我是一名维护程序员,我会为额外的间接级别感到高兴,任何有助于解决那些突然出现的边缘情况和特殊情况的东西总是有帮助的。如果他们从来不需要我就不会注意到/关心。
        【解决方案6】:

        就像任何取决于用法的东西一样,有一般规则,但实用性应该总是赢得争论。地图是干什么用的?您是否需要限制地图的内容,例如如果地图用于填充组合框,是否需要删除某些选项,例如,如果某些运营商仅处理某些包裹类型,则可以使用策略来填充地图,最好在枚举之外完成。

        尽管如此,我更喜欢在其他地方创建地图,这种额外的间接级别绝不会妨碍灵活性,并且现在可以节省很多痛苦并且增加很少的开销。您还可以对其进行编码,以便获得与其他枚举类似的功能。

        【讨论】:

          猜你喜欢
          • 2011-03-23
          • 1970-01-01
          • 1970-01-01
          • 2017-05-05
          • 1970-01-01
          • 2013-12-21
          • 1970-01-01
          • 2014-06-28
          • 2018-07-17
          相关资源
          最近更新 更多