简体   繁体   English

Java设计模式

[英]Java Design Patterns

I am having a class named DBObject which returns two different class objects.If the input string is water it returns object1 else object2. 我有一个名为DBObject的类,它返回两个不同的类对象。如果输入字符串是water,则返回object1 else object2。

My requirement is , now it it is returning objects based on if else...but in future some more objects will be added. 我的要求是,现在它是基于if else返回对象...但是将来会添加更多的对象。 So, instead of using elseif which makes code static, is there any dymanic way to return the class objects? 那么,不是使用使得代码静态的elseif,而是有任何回归方法来返回类对象吗?

I mean can i use any java design pattern in this scenario? 我的意思是我可以在这种情况下使用任何Java设计模式吗?

code: 码:

if(str=="water")
 return new object1()
else if...
     return new object3()
else if...
     return new object4()
else if...
     return new object5()
else if...
     return new object6()  
else
  return new object2()

First, replace if(str=="water") by if("water".equals(str)) . 首先,用if(str=="water") if("water".equals(str))替换if(str=="water") if("water".equals(str)) Operator == compares references while method equals() compares objects. Operator ==比较引用,而方法equals()比较对象。

Second, there are several approaches. 其次,有几种方法。 The first one is using dynamic class loading: Class.forName(className) . 第一个是使用动态类加载: Class.forName(className) In your case you can hold map between symbolic names and the fully qualified class names, so your code will look like: 在您的情况下,您可以在符号名称和完全限定的类名称之间保存映射,因此您的代码将如下所示:

Class.forName(map.get(str)).newInstance()

If your concrete classes list is not so dynamic you can use enum as a factory: 如果您的具体类列表不是那么动态,您可以使用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();

Going forward you can use dynamic discovery of available implementation using for example SPI: 展望未来,您可以使用SPI等动态发现可用的实现:

You're talking about implementation level here, not design level. 您在这里谈的是实施水平,而不是设计水平。 For implementation you need Java Reflection , which you can use like: 要实现,您需要Java Reflection ,您可以使用它,如:

Object obj = Class.forName(type).newInstance();

On design level Abstract Factory is the closest pattern. 在设计层面上, 抽象工厂是最接近的模式。

You could use a map, using String as key and java.lang.Class as value. 您可以使用映射,使用String作为键,使用java.lang.Class作为值。 Your classes probably share a common super class or interface, which you can specify as the generic type argument in your map definition: 您的类可能共享一个公共超类或接口,您可以在地图定义中将其指定为泛型类型参数:

Map<String, Class<? extends SomeSuperClass>> types = new HashMap<String, Class<? extends SomeSuperClass>>();
types.put("water", object1.class);

You can use reflection to create instances of classes (see http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html for further information): 您可以使用反射来创建类的实例(有关详细信息,请参阅http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html ):

SomeSuperClass instance = types.get("water").newInstance();

I would replace that string with an enum. 我会用枚举替换该字符串。 It clearly is something with a limited number of values that have special meanings, with only one instance of each required - exactly right for an enum. 它显然具有有限数量的值,具有特殊含义,每个只需要一个实例 - 完全适合枚举。 Plus you get better type-safety; 此外,您可以获得更好的类型安全性 someone can't pass in "fire" as the argument if it's not a valid thing to construct. 如果构建它不是一个有效的东西,有人不能传递"fire"作为论据。

If you do that: 如果你这样做:

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
    }
}

I think this is fairly easy to understand, and fairly stable as interfaces go. 我认为这很容易理解,而且接口相当稳定。

If there's more complexity in creating the objects, then rather than explicitly coding the new object1() logic in the cases, you might want to maintain a map of factory objects of some sort (still keyed off the enum). 如果在创建对象时更复杂,那么您可能希望维护某种类型的工厂对象的映射(仍然键入枚举),而不是在案例中显式编写new object1()逻辑。 The logic of the createObject method then would essentially be factoryMap.get(objType).constructInstance() . 然后, createObject方法的逻辑基本上是factoryMap.get(objType).constructInstance()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM