HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Best way to write generic factory in Java

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
genericfactorywaywritejavabest

Problem

I need to write a factory of generic converters to produce converters from/to MongoDB objects to/from Java objects. Here is my implementation, it doesn't look good enough to me, so I would like to see your advice.

public static  Converter getConverter(final Class clazz) {
    return new Converter() {
        public DBObject convert(T t) {
            if (clazz == Manager.class) {
                BasicDBObject dbObject = new BasicDBObject();
                dbObject.append("age", ((Manager) t).getAge());
                dbObject.append("id", ((Manager) t).getId());
                return dbObject;
            }
            throw new IllegalArgumentException("Unsuported Object Type " + clazz);
        }

        public T convert(DBObject o) {
            if (clazz == Manager.class) {
                int age= Integer.valueOf((String) o.get("age"));
                int id= Integer.valueOf((String) o.get("id"));
                Manager t = new Manager(id, age);
                return (T) t;
            }
            throw new IllegalArgumentException("Unsuported Object Type " + clazz);
        }
    };
}

Solution

When you see yourself going and editing the same function again and again to extend its functionality then thats a code smell. The problem is that whenever you add a type you have to add an if condition to your converter. So the conversion could be the class responsibility. in Java 8 you can use Suppliers for that and if you don't have Java 8 then Guava is your friend

Supplier convertToDBObject(){ // java 8 code
   Supplier supplier = ()-> {
     BasicDBObject dbObject = new BasicDBObject();
     dbObject.append("age", this.getAge());
     dbObject.append("id", this.getId());
     return dbObject;
   } 
  return supplier;
 }


Or implement Guava suppliers anonymously if you running java 6 or 7.
You can add an interface for convertable things that your classes can implement.

interface DBObjectConvertable{
   Supplier convertToDBObject();
}


and by doing so your types will be responsible for converting to DBObject in their own ways. The code smell in your code is adding ifs to the factory.Suppliers are factories but in a declarative way, so instead of returning converted object immediately, I will return you a function that knows how to convert to MongoDB objects.

Code Snippets

Supplier<DBObject> convertToDBObject(){ // java 8 code
   Supplier<DBObject> supplier = ()-> {
     BasicDBObject dbObject = new BasicDBObject();
     dbObject.append("age", this.getAge());
     dbObject.append("id", this.getId());
     return dbObject;
   } 
  return supplier;
 }
interface DBObjectConvertable{
   Supplier<DBObject> convertToDBObject();
}

Context

StackExchange Code Review Q#64188, answer score: 4

Revisions (0)

No revisions yet.