2

I have string which is from external source. Based on this string I have to generate an object. All object which I have to generated extend the same abstract base class. I have a list with relation "string" <-> "class".

My question is where is best way to do this generation and how?

  1. I can make separate class with method with if-else. And invoke it in place where I need.
  2. I can put it to this if-else direct in place where I need
  3. I can put it to abstract class.
  4. Add to abstract class Map<String,Class> and try to use reflection (but I don't know how)
  5. something else?

abstract class Element { 
    abstract String getType();
}
class AElement extends Element{
    String getType(){return "A";}
}
class BElement extends Element{
    String getType(){return "B";}
}
class CElement extends Element{
    String getType(){return "C";}
}

class MyObject {
   Element element;
   MyObject(String text){
   //here I conscruct my object form string.
   String[] elem = text.split(";");
   this.element = someMethod(elem[3]);
}

I know that elem[3] will be texts "A", "B" and "C" and then I should create in method someMethod() respective AElement, BElement or CElement object.

LunaVulpo
  • 3,043
  • 5
  • 30
  • 58
  • Can you please clarify a bit more or question, perhaps with a small example. From what I understand know, the string you receive is the name of the class of the object you have to create. If this is correct, then reflection can be a solution, namely if _a priori_ you don't know all the possible types of objects you may have to create. – João Fernandes Jul 19 '12 at 08:30

3 Answers3

3

Factory Pattern is a good solution. It'll abstract you from object creation techniques.

Inside the factory you can create instances via reflection like this:

public static YourAbstract createObject(String className) {
    try {
       Class c = Class.forName(className);
       YourAbstract newObject = (YourAbstract)c.newInstance();
       return newObject;
    } catch (Exception e) {
       // handle the way you need it ... e.g.: e.printStackTrace();
    }
}

Have a look at this question: Using reflection in Java to create a new instance with the reference variable type set to the new instance class name?

Or, in case all the classes are known to the factory, create some sort of map from config or something similar:

public class YourAbstractFactory {

    private static Map<String, Class> classez = new HashMap<String, Class>();

    public static YourAbstract initFactory(Map<String, Class> classes) {
        // initialize your map
        classez.putAll(classes);
    }

    public static YourAbstract initFactory(Collection<String> classes) {
        // initialize your map
        for(String className : classes) {
            try {
               Class c = Class.forName(className);
               classez.put(className, c);
            } catch (Exception e) {
               // handle the way you need it ... e.g.: e.printStackTrace();
            }
        }
    }

    public static YourAbstract createObject(String className) {
        try {
           Class c = classez.get(className);
           YourAbstract newObject = (YourAbstract)c.newInstance();
           return newObject;
        } catch (Exception e) {
           // handle the way you need it ... e.g.: e.printStackTrace();
        }
    }
}    
Community
  • 1
  • 1
Ostap Andrusiv
  • 4,827
  • 1
  • 35
  • 38
0

Best way is to use the Factory Pattern.

public static SomeObject createObject(String externalString){
 //construct the object(Have your If-else here)
 return someObject;
}
Chan
  • 2,601
  • 6
  • 28
  • 45
0

Use a Factory pattern that is able to create the provided object, based on it's input.

Buhake Sindi
  • 87,898
  • 29
  • 167
  • 228