Java 选择枚举类型时的好方法设计?

Java 选择枚举类型时的好方法设计?,java,methods,Java,Methods,以下两种方法中哪一种更好? 我选择枚举,因为在典型的情况下,子类型多态性是最好的方法;在编写简单的工厂方法时,这也是一种典型的方法 public class SomeClass { public SomeEnum returnAType(String someString) { //implementation bellow } private boolean method1() { //... } private boolean met

以下两种方法中哪一种更好? 我选择枚举,因为在典型的情况下,子类型多态性是最好的方法;在编写简单的工厂方法时,这也是一种典型的方法

public class SomeClass {
    public SomeEnum returnAType(String someString) {
        //implementation bellow
   }

   private boolean method1() {
   //...
   }

   private boolean method2() {
   //...
   }

   private boolean method3() {
   //...
   }

}
returnatype方法的首次实现;这会更快,因为如果method1有效,它不会调用method2和method3(可能还会调用更多)

    public SomeEnum returnAType(String someString) {
        if(method1(someString)) {
            SomeEnum.ENUM1.doSomething();
            return SomeEnum.ENUM1;
        }
        if(method2(someString)) {
            SomeEnum.ENUM2.doSomething();
            return SomeEnum.ENUM2;
        }
        if(method3(someString)) {
            SomeEnum.ENUM3.doSomething();
            return SomeEnum.ENUM3;
        }
        SomeEnum.DEFAULT_ENUM.doSomething();
        return SomeEnum.DEFAULT_ENUM;
   }
returnatype方法的第二次实现;这一点更加清晰,没有代码重复:

    public SomeEnum returnAType(String someString) {
        SomeEnum enumType = SomeEnum.DEFAULT_ENUM;
        if(method1(someString)) {
            enumType = SomeEnum.ENUM1;
        }
        if(method2(someString)) {
            enumType = SomeEnum.ENUM2;            }
        }
        if(method3(someString)) {
            enumType = SomeEnum.ENUM3;
        }
        enumType.doSomething();
        return enumType;
   }

我很想用

public SomeEnum returnAType(String someString) {
    SomeEnum enumType = method1(someString) ? SomeEnum.ENUM1 :
                        method2(someString) ? SomeEnum.ENUM2 :
                        method3(someString) ? SomeEnum.ENUM3 : SomeEnum.DEFAULT_ENUM;
    enumType.doSomething();
    return enumType;

}

我发现Java枚举非常令人困惑,通常我建议在不简单枚举时尽量避免枚举。您可以将代码组织成一个接口或抽象类,以及几个实现该接口或抽象类的单例。最终的设计更清晰,更容易理解

我强烈建议尽量避免使用返回T并在内部调用T.someMethod的方法。这种模式又一次令人困惑和误导。将returnAType视为单例的工厂方法,此函数的目标只是返回正确的单例类型

如果函数不使用某些模式,而是使用简单的等式,请使用数据结构存储键值关联。不是像有人说的EnumMap,因为在EnumMap中,Enum是键,而不是值

事实上,@Peter Lawrey给你的一条评论强调了如果你不遵循第二条建议你会遇到的问题:不要编写一个返回t并通过t产生副作用的方法。我的建议是部分遵循它的建议,但以这种方式将副作用转移到外部:

// Beautiful and testable with no side-effects

public SomeEnum returnAType(String someString) {
    SomeEnum enumType = method1(someString) ? SomeEnum.ENUM1 :
                        method2(someString) ? SomeEnum.ENUM2 :
                        method3(someString) ? SomeEnum.ENUM3 : SomeEnum.DEFAULT_ENUM;

    return enumType;
}

// Do something for real
public void doSomethingWith(String someString) {
    SomeEnum enumType = returnAType(someString);
    enumType.doSomething();
}

在Java 7中,可以对字符串使用
开关

使用构造函数
SomeEnum(Integer){..;}
在其他地方类
SomeEnum

它可以是
private
,就像在
Pattern.class
示例中一样,因此它应该是
returnsomeenum.set(1)

然后您可以根据需要使用SomeEnum

某些模型不喜欢中间返回,因此,您可以在其中添加一个临时SomeEnum,并在末尾返回它

typeOf SomeEnum
enum

public SomeEnum returnAType(final String someString) {
     switch (someString.toLowerCase()) { //toLowerCase() if needed
        case "one":
            return SomeEnum.ENUM1;
            // break; // Normaly break; is unused, you can  remove it
        case "two":
            return SomeEnum.ENUM2;
        case "three":
            return SomeEnum.ENUM3;
        default: 
            return SomeEnum.DEFAULT_ENUM; 
      }
}

如果方法1、方法2和方法3为真怎么办?如果选择返回方法,则考虑第一种方法;如果没有,最后一个。使用if-else方法(如下面建议的那样)就像返回一样-选择第一个。枚举到底有多混乱?枚举非常适合那些可以在离散的、可枚举的集合中假设值的东西,但是根据我的个人经验,它们往往误导设计,让人们编写充满切换的代码,如果(因为它们是枚举)。如果它们被类层次结构和多态性以及其他设计模式(如工厂方法)的正确使用所取代,那么最终的设计通常会更干净。除了为hibernate编写自己的用户类型对象这一头疼的问题,以及其他切换实际实现对象很困难的情况。如果您确实需要到,你可以向枚举对象添加行为(除非你真的需要,否则我不会这样做,但这是可以做到的)。看这个粘贴箱:啊,我认为Hibernate是大约10年的技术,你只在教科书中读到过,人们已经了解ORM是危险和有害的:)@Edmondo1984:使用枚举时,你不必写太多的if-else;您只需要在初始化时编写它们,这与典型的工厂方法相同。在其他情况下,您迭代Enum.values()并对所有类型执行该操作;您没有公共构造函数。
public SomeEnum returnAType(final String someString) {
     switch (someString.toLowerCase()) { //toLowerCase() if needed
        case "one":
            return SomeEnum.ENUM1;
            // break; // Normaly break; is unused, you can  remove it
        case "two":
            return SomeEnum.ENUM2;
        case "three":
            return SomeEnum.ENUM3;
        default: 
            return SomeEnum.DEFAULT_ENUM; 
      }
}