2017-05-09 50 views
1

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

ex:考虑学校为枚举,常量是TEACHER(LOWLEVELACCESS),STUDENT(NOACCESS),OFFICEADMIN(OFFICEACCESS)。

在枚举,我有抽象方法过程其接收用户POJO,字符串作为参数,并更新在对象的某些字段和返回相同的USER POJO(与更新的)给调用者。通过这个,我可以在枚举本身中同步常量和它们的逻辑。

所以我的问题,

  1. 它是正常的有枚举此实现? (我已经看到大多数的例子对待枚举来存储常量值而不使用它们进行任何计算)

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

  3. 是否有可能在enum中创建getter/setter方法?

在此先感谢!

+1

你可以发布一些(伪)代码后,你是什么?基本上你可以添加方法来枚举并在那里进行计算,但它会让我觉得它是一种设计气味(至少不知道更多)。 – Thomas

+0

@Thomas我同意关于潜在的设计气味。我不会一概而论,但我认为,如果您以这种方式利用枚举,可能会出现这种情况。 – davidxxx

+0

枚举常量具有行为是完全可以接受和习惯的。认为“代码味道”就是否定自己90%的枚举能力。 –

回答

5

恕我直言:

  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. 是否可以在枚举中创建getter/setter方法?

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

    +0

    嗨@OldCurmudgeon,我想问一下“每个枚举的一个实例的意思是什么”。例如:如果我有像枚举水果那样的枚举{ } \t APPLE,ORANGE; },这里将创建两个枚举实例吗?一个是fruits.APPLE&fruits.ORANGE –

    +0

    @prababuddy - 这意味着有一个** APPLE,无论你在哪里使用它。例如。如果你允许'APPLE.setColour(..)'那么**所有**苹果都会改变颜色。 – OldCurmudgeon

    4

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

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

    这种计算可以通过在类中使用的方法来完成,什么是 好处,如果我这样做枚举法的计算?

    你在对象方面的原因。您不需要在代码中创建服务和间接寻址,因为作为域对象的枚举执行计算。
    枚举值和相关的处理构成了同样的问题。所以,收集它们不是一个难闻的气味。
    尽管如此,请注意如果您开始编写大量在枚举方法中做了非常不同的事情的处理,您应该将它们排除在枚举之外。
    这是一种难闻的气味,因为枚举不应该成为上帝的对象。

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

    提供数据,是的,但设置枚举的数据:不,你不能。
    否则,您会构建一个有状态的服务,并冒着完成同步问题的风险。

    +0

    Hi @davidxxx,只是为了解枚举水果{APPLE,ORANGE; }根据我的理解,这里创建了两个枚举实例,它们被认为是单例。如果有任何问题,请纠正我的内容。因此,问题是枚举实例内部是什么? –

    +0

    你好,我不知道你的问题。抱歉。 – davidxxx

    +0

    感谢您的回复..我尽量让问题更简单...例如:enum fruits {APPLE,ORANGE; }将为此枚举创建多少个实例?如果两个实例将被创建,我们怎么能说枚举是单身? –

    0

    枚举被定义为final。只要结果对于相同的输入是相等的,就允许计算。 您也可以修改输入实例,但不应在枚举中定义任何setter,因为在这种情况下枚举不是不可变的。

    另请参见Example 8.9.2-4 here