我从设计的角度一直想知道,将枚举作为参数传递给工厂类(而不是字符串)是否更好?
以下面的代码为例:
class SomeFactory{
public SomeObject getObject(String objectType){
switch(objectType){
case "TYPEA":
return new SomeObjectA();
case "TYPEB":
return new SomeObjectB();
default:
{handle the situation of missing / or misspelled request here}
}
}
}
现在,我相信上面的实现很容易出错,在IDE中,您必须导航到工厂类源并查看可接受的输入内容...
而不是这样做,我认为创建一个公共的内部枚举,例如SOMEOBJECTS,并在其中存储所有可能的变体,将是一个更加安全的选择。
实现看起来像这样:
class SomeFactory{
// public inner enum that can be accessed through the factory.
public enum SOMEOBJECTS{
TYPEA,
TYPEB,
TYPE...
}
public SomeObject getObject(SOMEOBJECTS objectType){
switch(objectType){
case TYPEA:
return new SomeObjectA();
case TYPEB:
return new SomeObjectB();
default:
// Putting a default as a good practice, even though the input now has been
// restricted to whatever is inside the enum class.
}
}
}
我唯一想到的警告是,要访问枚举,您必须键入SomeFactory.SOMEOBJECTS.TYPE..;
。
也许我对此很着迷,但是我相信,每当更新工厂类时,枚举类中需要的这额外的代码行都会走很长的路。
[我经常在书和在线文章中看到使用String作为参数的Java工厂模式的第一个示例。
您是否同意这种方法,或者在实现工厂模式时还有我不知道的更好的方法?
我认为使用枚举实现它的方式将是使用String的更好方法。
将枚举作为内部类型是有意义的,因为枚举内的值直接与SomeFactory有关。
如果您希望从传递给应用程序的String值中获取枚举,则可以始终这样做:
SomeObjects.valueOf(string.toUpperCase());
((字符串是传递到您的应用程序中的字符串值)
使用枚举显然是最好的方法,因为它使您安全地确保每个调用都具有有效的参数。当然,这会带来维护的开销,但是您应该更喜欢这样做,而不是因为某些字符串无效而使程序崩溃。
我想提到的另一件事是,有一个工厂创建不同类型的实例很奇怪。工厂类应专门针对一种类型。然后,您将不必传递类型作为参数。您也可以使用多个getObject
方法,这些方法的类型显式作为参数。
FYI:您可以按类型传递type。
public static <T> T blubb(Class<T> type)
throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException {
return type.getConstructor().newInstance();
}
public static void main(String[] args) {
try {
Object o = blubb(Object.class);
} catch (Exception e) {
// I don't care.
}
}
这显然很糟糕,但是也许这会让您对这个话题有另一种看法。