有人能推荐Java8模式来代替switch语句吗?
我有以下代码:有人能推荐Java8模式来代替switch语句吗?,java,design-patterns,java-8,Java,Design Patterns,Java 8,我有以下代码: public class A { private String type; String getType() { return type;} } 现在在很多代码地方我都有这样的代码 switch (a.geType()) { case "A" : return new Bla(); case "B" : return new Cop(); } 或者别的什么地方 switch (a.geType()) { case "A" : return
public class A {
private String type;
String getType() { return type;}
}
现在在很多代码地方我都有这样的代码
switch (a.geType()) {
case "A" : return new Bla();
case "B" : return new Cop();
}
或者别的什么地方
switch (a.geType()) {
case "A" : return new Coda();
case "B" : return new Man();
}
(请注意,我知道应该在生产代码中使用枚举)
我想实现的是,当一个新类型被添加到类a中时,编译器应该标记所有需要调整的switch语句
有没有java惯用的方法来实现这一点
当一个新类型被添加到类a
时,编译器应该标记所有需要调整的开关
语句
解决这一问题的一个好方法是用更健壮的多分派实现替换switch
语句,例如:
有了这个基础结构,您可以删除开关
语句,用访问者的实现替换它们:
Object res = a.accept(new VisitorOfA() {
public Object visitA(A a) { return new Bla(); }
public Object visitB(B b) { return new Cop(); }
});
当您向a
添加一个新的子类型时,比如说,类C
,您所需要做的就是向访问者a
添加一个新方法:
Object visitC(C c);
现在,编译器将发现所有未实现此新方法的地方,帮助您避免运行时出现问题。您可以拥有字符串/供应商的地图:
Map<String, Supplier<Object>> map = new HAshMap<> ();
map.put("A", Bla::new);
map.put("B", Cop::new);
不要忘记好的老式多态性。在类中有一个带有switch语句的“type”字段通常是一种气味,表明子类化可能很有用。考虑:
public abstract class CommonSuperClass {
public abstract One getOne();
public abstract Two getTwo();
}
public class A extends CommonSuperClass {
@Override public One getOne() { return new Bla(); }
@Override public Two getTwo() { return new Coda(); }
}
public class B extends CommonSuperClass {
@Override public One getOne() { return new Cop(); }
@Override public Two getTwo() { return new Man(); }
}
如果要添加一个新的子类C,则需要提供抽象方法的实现(除非将C本身抽象化)。从抽象的角度来看,还有另一种方法可供使用。一种方式是通过 一些简单的例子:
public void EverythingYouWant (Animal animal) {
return animal.move();
}
当更多的是关于重构模式时。这是一个很好的解决方案,首先考虑是否有防止子类化的原因。 如果您使用枚举,我很确定java确实会标记不处理该条件的switch语句,只要该开关没有
默认值
条件。我只是尝试了一下。它不会将缺少的枚举标记出来,我这样做时会在eclipse中收到警告。不过,它可能不是java编译器本身的一部分。不知何故,switch语句看起来更轻量级,因此对于阅读代码的人来说更容易理解。但我必须承认,您的答案解决了“编译器标记”的要求。这种方法的一个很好的改进是将每个实现的一个实例存储到映射中。此外,您可以从.properties文件加载地图。@jack我同意,访问者模式对于第一次查看它的人来说看起来很棘手。我在这里有很大的偏见,因为我已经使用这种模式很多年了。然而,其优点是,人们只需要学习一次这种模式,就可以在将来可靠地识别它。这就像学习骑自行车一样:)访客模式对于预期会改变的类层次结构来说是一个糟糕的解决方案。GoF在第333页描述了访客的成本/收益。“当定义对象结构的类很少更改,但您通常希望在结构上定义新操作时,请使用访问者模式。更改对象结构类需要为所有访问者重新定义接口,这可能代价高昂。如果对象结构类经常更改,则最好定义e这些类中的操作。”
public abstract class CommonSuperClass {
public abstract One getOne();
public abstract Two getTwo();
}
public class A extends CommonSuperClass {
@Override public One getOne() { return new Bla(); }
@Override public Two getTwo() { return new Coda(); }
}
public class B extends CommonSuperClass {
@Override public One getOne() { return new Cop(); }
@Override public Two getTwo() { return new Man(); }
}
public void EverythingYouWant (Animal animal) {
return animal.move();
}