Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java设计模式_Java_Design Patterns - Fatal编程技术网

Java设计模式

Java设计模式,java,design-patterns,Java,Design Patterns,我有一个名为DBObject的类,它返回两个不同的类对象。如果输入字符串是water,它将返回object1,否则返回object2 我的要求是,现在它返回基于if-else的对象…但在将来会添加更多的对象。那么,除了使用使代码静态的elseif之外,还有什么动态的方法来返回类对象吗 我的意思是,我可以在这个场景中使用任何java设计模式吗 代码: 这里说的是实现级别,不是设计级别。对于您需要的实现,您可以使用以下方法: Object obj = Class.forName(type).newI

我有一个名为DBObject的类,它返回两个不同的类对象。如果输入字符串是water,它将返回object1,否则返回object2

我的要求是,现在它返回基于if-else的对象…但在将来会添加更多的对象。那么,除了使用使代码静态的elseif之外,还有什么动态的方法来返回类对象吗

我的意思是,我可以在这个场景中使用任何java设计模式吗

代码:
这里说的是实现级别,不是设计级别。对于您需要的实现,您可以使用以下方法:

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();