views:

59

answers:

2

I need to create objects by reading their description from a text file. The objects are also in a hierarchy or can be decorative objects For example

For this descrition in a text file:

Sample.txt


A FileReader "fileName.txt"

A Buffered FileInput reader "FileName.txt"

A Buffered StringInput reader "TestString"


The program should read this description and return a list of suitable readers

new FileReader("fileName.txt")

new BufferedReader(new FileReader("FileName.txt"))

new BufferedReader(new StringReader("TestString"))

Is there any way to achieve it? Factory pattern can be used to achieve this IMHO.

+1  A: 

Surely you can do it with a Factory, but to me it sounds more like a job for a Builder. (You can of course use the Factory interface, and implement it as a Builder too).

A Builder is more suitable for creating a complex object hierarchy based on varying input, like in your case. My first idea is to use a Map<String, Class> and parse the lines from the file backwards: the last parameter is the filename, then each word (group) would map to a specific class, which you instantiate by passing it the previous result.

Péter Török
A: 

If all your real cases are so simple as example in your question then you can use what you like (i.e. what you've already used before).

But if more complex cases exist then you should provide some kind of parser first. Even for last string in your example it's not so simple to generate necessary code:

public Object buildObject (Parser parser, Item param) {
   if (!parser.hasNext ()) {
      return param.getValue ();
   }
   Item nextItem = parser.getNextItem (); //1st call: "TestString", 2nd call: "StringReader"
   if (nextItem.isParameter ()) {         //1st call: true, 2nd call: false 
      return buildObject (parser, nextItem);
   } else if (nextItem.isClassName () {   //2nd call: true
      Class c = Class.forName (nextItem.getStringValue ());
      Constructor ctr = c.getConstructor (param.getClassName ()); //getClassName returns "String"
      Object obj = ctr.newInstance (param.getValue ());
      return buildObject (parser, new Item (obj));
   } else {
      throw new ParseException ("Illegal input");
   }   
}

This peace of code is still very buggy (there is no try/catch, there is no some necessary logic), but it demonstrates the basic idea (and this idea is about it's not so easy task).

Maybe it's worth to look for some 3rd party libs (even if you have to sacrifice your file format and accept their format).

Roman
What third party libs do you suggest which offer such flexibility
sushant
use google or ask separate question at SO
Roman