Java设计模式
我有一个名为DBObject的类,它返回两个不同的类对象。如果输入字符串是water,它将返回object1,否则返回object2 我的要求是,现在它返回基于if-else的对象…但在将来会添加更多的对象。那么,除了使用使代码静态的elseif之外,还有什么动态的方法来返回类对象吗 我的意思是,我可以在这个场景中使用任何java设计模式吗 代码:Java设计模式,java,design-patterns,Java,Design Patterns,我有一个名为DBObject的类,它返回两个不同的类对象。如果输入字符串是water,它将返回object1,否则返回object2 我的要求是,现在它返回基于if-else的对象…但在将来会添加更多的对象。那么,除了使用使代码静态的elseif之外,还有什么动态的方法来返回类对象吗 我的意思是,我可以在这个场景中使用任何java设计模式吗 代码: 这里说的是实现级别,不是设计级别。对于您需要的实现,您可以使用以下方法: Object obj = Class.forName(type).newI
这里说的是实现级别,不是设计级别。对于您需要的实现,您可以使用以下方法:
Object obj = Class.forName(type).newInstance();
在设计级别上是最接近的模式。您可以使用映射,使用字符串作为键,使用java.lang.Class作为值。您的类可能共享一个通用的超类或接口,您可以将其指定为映射定义中的泛型类型参数:
Map<String, Class<? extends SomeSuperClass>> types = new HashMap<String, Class<? extends SomeSuperClass>>();
types.put("water", object1.class);
我将用枚举替换该字符串。很明显,它的值数量有限,具有特殊含义,每个值只需要一个实例,对于枚举来说完全正确。此外,您还可以获得更好的类型安全性;如果“fire”不是一个可构造的有效对象,则不能将其作为参数传递 如果您这样做:
public enum ObjectType {
WATER,
AIR,
EARTH
}
public static Foo createObject(ObjectType objType) {
switch (objType) {
case WATER: return new object1();
case AIR: return new object2();
case EARTH: return new object3();
default: // throw new IllegalArgumentException or something similar
}
}
我认为这相当容易理解,并且随着接口的发展也相当稳定
如果创建对象更为复杂,那么您可能需要维护某种类型的工厂对象的映射(仍然关闭枚举),而不是在这种情况下显式地编码newobject1()
逻辑。createObject
方法的逻辑基本上是factoryMap.get(objType).constructInstance()
首先,将if(str==“water”)
替换为if(“water”.equals(str))
。运算符==
比较引用,而方法equals()
比较对象
第二,有几种方法。第一个是使用动态类加载:class.forName(className)
。在本例中,您可以在符号名和完全限定类名之间保持映射,因此您的代码如下所示:
Class.forName(map.get(str)).newInstance()
如果您的具体类列表不是如此动态,您可以使用enum
作为工厂:
enum Factory {
red {
public Color create() {
new Red();
}
},
green {
public Color create() {
new Green();
}
};
public abstract Color create();
}
String colorName = ...;
Color c = Factory.valueOf(colorName).create();
接下来,您可以使用可用实现的动态发现,例如SPI:
str==“water”
,你确定吗?为什么不切换String.hashCode()?@MarekSebera:java7也支持String的开关大小写。@Nandkumar从1.7开始,我们讨论支持旧设备或JREin,有些地方我们需要类似的东西,但出于安全原因,请将类名和密钥保留在db中。
public enum ObjectType {
WATER,
AIR,
EARTH
}
public static Foo createObject(ObjectType objType) {
switch (objType) {
case WATER: return new object1();
case AIR: return new object2();
case EARTH: return new object3();
default: // throw new IllegalArgumentException or something similar
}
}
enum Factory {
red {
public Color create() {
new Red();
}
},
green {
public Color create() {
new Green();
}
};
public abstract Color create();
}
String colorName = ...;
Color c = Factory.valueOf(colorName).create();