我对代码风格有疑问:
假设我有一个包含一些信息的字符串(如“Information1”或“Information2”)。基于此我想用工厂创建对象。显然我可以这样写:
if(string.equals("Information1")){
Factory.createInformation1Object();
}
if(string.equals("Information2")){
Factory.createInformation2Object();
}
if(string.equals("Information3")){
Factory.createInformation3Object();
}
现在我想知道是否有更好(更漂亮)的方法来做到这一点。我非常喜欢访问者模式的多重派遣理念,但我无法轻易地将这种方法应用于此特定问题。
答案 0 :(得分:7)
您可以使用abstract factory pattern。
创建一个抽象的Factory
类[或接口],以及扩展它的类:MyObject1Factory
,MyObject2Factory
,...
在预处理时,将Map<String,Factory>
从String
填充到相应的Factory
实例,这只在您的应用中完成一次。
当您需要创建新实例时 - 调用map.get(string).create()
来创建相关类型的相关对象。
编辑:代码为的小例子
你的课程是:
public static class MyBase {
@Override
public String toString() {
return "Base";
}
}
public static class Class1 extends MyBase {
@Override
public String toString() {
return "Class1";
}
}
public static class Class2 extends MyBase {
@Override
public String toString() {
return "Class2";
}
}
你的工厂将是:
public static abstract class MyFactory {
public abstract MyBase build();
}
public static class MyFactory1 extends MyFactory {
@Override
public Class1 build() {
return new Class1();
}
}
public static class MyFactory2 extends MyFactory {
@Override
public Class2 build() {
return new Class2();
}
}
在程序生命周期中填充地图 :
Map<String,MyFactory> map = new HashMap<String, Test.MyFactory>();
map.put("class1", new MyFactory1());
map.put("class2", new MyFactory2());
当您需要新对象时,请调用:
MyBase obj = map.get(s).build();
System.out.println(obj);
(*)注意:类的static关键字在这里,因为我将它们创建为内部类 - 当然,如果不是你的情况,你需要省略它....
答案 1 :(得分:3)
在Java 7中,您现在可以在switch语句中使用字符串。
请注意,您的代码与switch语句不直接相关,因为理论上可以通过查看代码的结构来调用所有三个工厂方法(例如,没有else
语句)。但实际上这是不可能发生的,因为string
不能同时拥有所有三个值。
答案 2 :(得分:0)
我更喜欢功能性和可读性。 :-)如果string为null并且调用它的方法肯定会抛出NPE,请考虑以下内容,
"Information1".equals(strings)
也许Information1,Information2和Information3可以作为类静态变量放置,因此可以很容易地引用并防止人为错误。
答案 3 :(得分:0)
您可以在Java 7中新使用switch
语句。here
答案 4 :(得分:0)
最好使用switch-case,因为如果第一次或第二次检查为真,则会进行不必要的检查。 在默认部分,您可以放置其他活动,例如抛出异常等。