patternjavaMinor
Best way to write generic factory in Java
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
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.
and by doing so your types will be responsible for converting to
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.