Java 使用枚举选择内部实现

Java 使用枚举选择内部实现,java,constructor,enums,public,Java,Constructor,Enums,Public,任务:拥有一个以不同方式实现某些东西的类。类的用户应该只看到表示可用选项的公共枚举,同时隐藏不同行为的所有实现 为了避免在每次调用方法时检查提供的“样式”,构造函数对提供的枚举值使用开关,将适当的内部私有类分配给字段 以下是SSCCE: public class Greeter { public enum GreetingStyle { HEY, HELLO } private String name; private GreetingChooser greetingC

任务:拥有一个以不同方式实现某些东西的类。类的用户应该只看到表示可用选项的
公共枚举
,同时隐藏不同行为的所有实现

为了避免在每次调用方法时检查提供的“样式”,构造函数对提供的枚举值使用
开关
,将适当的内部私有类分配给字段

以下是SSCCE:

public class Greeter {
    public enum GreetingStyle { HEY, HELLO }

    private String name;
    private GreetingChooser greetingChooser;
    public Greeter(String name, GreetingStyle style) {
        this.name = name;
        switch(style) {
            case HEY:
                greetingChooser = new Hey();
                break;
            case HELLO:
                greetingChooser = new Hello();
                break;
            default :
                throw new UnsupportedOperationException("GreetingStyle value not handled : " + style.toString());
        }
    }

    public void greet() {
        // need to avoid switch(style) here
        System.out.println(greetingChooser.greeting() + ", " + name + "!");
    }

    // this interface can't be public
    private interface GreetingChooser {
        String greeting();
    }

    private class Hey implements GreetingChooser {
        public String greeting() {
            return "Hey";
        }
    }

    private class Hello implements GreetingChooser {
        public String greeting() {
            return "Hello";
        }
    }

    public static void main(String args[]) {
        new Greeter("John Doe", Greeter.GreetingStyle.HEY).greet();
        new Greeter("John Doe", Greeter.GreetingStyle.HELLO).greet();
    }
}
问题:实现这样一个功能以使其在将来可维护(例如,我们需要添加
GreetingStyle ALOHA
)是一种好方法吗?我的另一个想法是使用静态地图

private static final Map<GreetingStyle, GreetingChooser> greetingMap;
static {
    greetingMap = new HashMap<>();
    greetingMap.put(Greeter.GreetingStyle.HEY, new Hey());
    greetingMap.put(Greeter.GreetingStyle.HELLO, new Hello());
}
私有静态最终地图迎宾地图;
静止的{
greetingMap=新HashMap();
greetingMap.put(Greeter.GreetingStyle.HEY,new HEY());
greetingMap.put(Greeter.GreetingStyle.HELLO,newhello());
}
并在构造函数中使用
greetingMap.get(style)


注意:在Java 8中,最好使用lambdas实现它(如果接口只有一个函数),但我只能使用Java 7。

为什么要绑定到枚举?使用多态性可以很容易地实现您所描述的内容。如果您担心将来扩展它,您可以使用设计模式,例如Factory或Decorator。

而不是将枚举作为工厂开关的常量,您可以通过为枚举常量配备两种配置来避免开关

public enum GreetingStyle 
{ 
    HEY("Hey"),
    HELLO("Hello");

    GreetingStyle(String text) {
        this.text = text;
    }

    public final String text;
}
或行为:

public enum GreetingStyle 
{ 
    HEY {
        public void greet() { /* performs hey style greeting*/ }
    },
    HELLO{
        public void greet() { /* performs hello style greeting*/ }
    };

    public abstract void greet();
}

您可以将
greet
作为抽象放在
enum
中,并以
GreetingStyle结束。嘿,greet(“JohnDoe”)
,请参见此示例。只有enum是公共的,可以对类的用户隐藏实现。但这会使
greet
成为公共的。Java似乎不允许在枚举内使用私有抽象方法。@andrybak这可能是问题,也可能不是问题,取决于具体情况。奇怪的是,Java允许在外部类可以访问的内部类内使用私有方法,但不允许在内部枚举内使用私有方法。编辑:问题是我们不能覆盖子类中的私有方法,枚举只是构建隐藏类层次结构的语法糖。