【问题标题】:enums to do the computation枚举进行计算
【发布时间】:2017-05-09 08:41:33
【问题描述】:

我们可以将对象传递给枚举抽象方法并在枚举中进行计算吗?这是一个场景,我有四个常量,每个常量都有自己的值。基于常量,我将在我的方法中进行计算。相反,我想在枚举中进行计算并希望得到响应。要在枚举中进行计算,我必须将两个/三个引用对象传递给枚举方法......

例如:将学校视为枚举,常量为 TEACHER(LOWLEVELACCESS)、STUDENT(NOACCESS)、OFFICEADMIN(OFFICEACCESS)。

在枚举中,我有抽象方法 process,它接收 USER POJO、字符串作为参数并更新对象中的某些字段,并将相同的 USER POJO(更新后)返回给调用者。这样我就可以在枚举本身中同步常量及其逻辑。

所以我的问题,

  1. 在枚举中有这个实现可以吗? (我已经看到大多数示例将枚举处理为存储常量值而不将它们用于任何计算)

  2. 这种计算可以通过使用类中的方法来完成,如果我在枚举方法中进行计算有什么好处?

  3. 是否可以在枚举中创建getter/setter方法?

提前致谢!!

【问题讨论】:

  • 你能发布一些关于你所追求的(伪)代码吗?基本上你可以向枚举添加方法并在那里进行计算,但它让我觉得设计味道很糟糕(至少不知道更多)。
  • @Thomas 我同意潜在的设计气味。我不会一概而论,但我认为如果您以这种方式过度利用枚举,可能会出现这种情况。
  • 枚举常量具有行为是完全可以接受和惯用的。考虑到“代码气味”就是否定了自己 90% 的枚举能力。

标签: java enums


【解决方案1】:

恕我直言:

  1. 在枚举中有这个实现可以吗?

是的 - 我一直这样做。

enum Ops implements Op {
    Nop{
        @Override
        public int filter(int old, int now) {
            // Unchanged.
            return now;
        }
    },
    Diff{
        @Override
        public int filter(int old, int now) {
            return a(now)
                    | (Colour.MidGrey + (r(now) - r(old))) << 16
                    | (Colour.MidGrey + (g(now) - g(old))) << 8
                    | (Colour.MidGrey + (b(now) - b(old)));
        }
    };
}
  1. 这种计算可以通过使用类中的方法来完成,如果我在枚举方法中进行计算有什么好处?

该功能的代码在一个位置。这总是一件好事。

  1. 是否可以在枚举中创建 getter/setter 方法?

是的 - 但不要。请记住,在代码的整个生命周期中,每个enum 都有一个 实例。在全局对象上添加/删除功能很可能会在以后对您造成伤害。

【讨论】:

  • 嗨@OldCurmudgeon,我想问“一生中每个枚举的一个实例是什么意思”..例如:如果我有像枚举水果{苹果,橙色; },这里将创建两个枚举实例,对吗?一种是fruits.APPLE & fruits.ORANGE
  • @prababuddy - 这意味着有一个 APPLE,无论你在哪里使用它。例如。如果您允许APPLE.setColour(..),那么所有苹果都会改变颜色。
【解决方案2】:

在枚举中有这个实现可以吗?

这是一种设计选择。
Enum 带来了一些advdantanges 来提供服务操作。
枚举值是开箱即用的单例,这些是不言自明的,有内存效率等......但也有一些限制,你不能直接从枚举派生,所以如果你想你应该在枚举后面引入一个接口能够测试您的代码并避免将执行计算的客户端类与枚举耦合...如果以后您改变了对枚举使用的想法。

这个计算可以通过使用类中的方法来完成,什么是 如果我在枚举方法中进行计算会受益吗?

你根据对象进行推理。您无需在代码中创建服务和间接寻址,因为作为域对象的枚举会进行计算。
枚举值和相关的处理是相同关注点的一部分。因此,收集它们不一定是难闻的气味。
不过,请注意,如果您开始编写大量处理方法,在枚举方法中执行非常不同的操作,您可能应该将它们删除枚举。
这是一种难闻的气味,因为枚举不应该成为上帝的对象。

是否可以在枚举中创建getter/setter方法?

提供数据,是的,但是设置枚举的数据:不,你不能。
否则,您将构建有状态服务,并且可能会遇到同步问题。

【讨论】:

  • 嗨@davidxxx,只是为了理解枚举水果{苹果,橙色; },根据我的理解,这里创建了两个枚举实例,它们被认为是单例的。如果有任何问题,请纠正我的理解。所以问题是枚举实例内部是什么?
  • 您好,我不确定您的问题是否理解。对不起。
  • 感谢您的回复.. 我尽量让问题更简单... 例如: enum fruits { APPLE,ORANGE;将为此枚举创建多少个实例?如果要创建两个实例,我们怎么能说枚举是单例的?
  • 没什么 :) 我现在明白了。枚举类本身不是单例,枚举值/常量是。在您的情况下,您将通过枚举值/常量拥有一个单例实例。所以你有 2 个单身人士。
【解决方案3】:

枚举被定义为最终的。只要相同输入的结果相等,就可以进行计算。 您也可以修改输入实例,但不应在枚举中定义任何设置器,因为在这种情况下枚举不是不可变的。

另见Example 8.9.2-4 here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多