Reputation: 1466
I'm working on a Android Java project and I have hunch that I will be able to use a better pattern for a situation that accures in two places.
I have a class wich builds ContentValues (basically key/value object) from a inputed model/object and returns a ContentValue object which have different key/values depending on which object I'm inputing.
Currently, there is a method for each object I want to generate ContentValues for. E.g:
public ContentValues BuildPage (Page p){
ContentValues val = new ContentValues();
val.put(PAGE_DESCRIPTION, p.getDesciption());
val.put(PAGE_DISPLAYABLE, BitmapHelper.ConvertToBlob(p.getPic()));
val.put(PAGE_MODULE_ID, p.getModuleId());
val.put(PAGE_TITLE, p.getTitle());
return val;
}
public ContentValues BuildQuestion(Question q){
ContentValues val = new ContentValues();
val.put(QUESTION_CORRECT, q.getCorrect());
val.put(QUESTION_QUESTION, q.getQuestion());
val.put(QUESTION_QUIZ_ID, q.getQuizId());
return val;
}
My intuition tells me that there probably is a better way of doing it.
The second situation is almost the opposite. I input the same object, builds different objects and returns them. E.g:
public Quiz BuildQuizObj(Cursor c){
//{QUIZ_ID, QUIZ_MODULE_ID};
Quiz q = new Quiz();
if(CursorIsOk(c)){
c.moveToFirst();
q.setId(c.getLong(0));
q.setModuleId(c.getLong(1));
}
return q;
}
public Module BuildModuleObj(Cursor c){
List<Module> modules = BuildModulesObj(c);
Module m = new Module();
if(modules.size() > 0){
m = modules.get(0);
}
return m;
}
So my question is: Is there any design pattern I can use to make the same functionality in a more generalized way so I can use the same method instead of creating new methods for each new object i want to use?
Upvotes: 1
Views: 1416
Reputation: 3263
You can use interfaces and generics, e.g. like this :
Edit: Old stuff at bottom!
public interface Buildable {
public ContentValues values();
}
public interface Builder<S, T extends Buildable> {
public T build(S source);
}
public class Module implements Buildable {
@Override
public ContentValues values() {
ContentValues c = new ContentValues();
c.put("name", getClass().getName());
return c;
}
}
public class ModuleFromCursorBuilder implements Builder<Cursor, Module> {
@Override
public Module build(Cursor source) {
return new Module();
}
}
public class QuizFromCursorBuilder implements Builder<Cursor, Quiz> {
@Override
public Quiz build(Cursor source) {
return new Quiz();
}
}
Cursor cursor = null;
Log.i("ModuleFromCursorBuilder",new ModuleFromCursorBuilder().build(cursor).values().get("name")+"");
Log.i("QuizFromCursorBuilder",new QuizFromCursorBuilder().build(cursor).values().get("name")+"");
...now you could generalize your S and T even more, more interfaces... endless story.
---- Old Stuff ----
public interface Buildable<T> {
public T build(Cursor c);
}
public class ModuleBuilder implements Buildable<Module>{
@Override
public Module build(Cursor c) {
return new Module();
}
}
public class QuizBuilder implements Buildable<Quiz>{
@Override
public Quiz build(Cursor c) {
return new Quiz();
}
}
Now you just call one method, build, and you get the object.
You also do it like this with your first problem...
public interface Valuable {
public ContentValues values();
}
public class Question implements Valuable {
@Override
public ContentValues values() {
return new ContentValues();
}
}
public class Page implements Valuable {
@Override
public ContentValues values() {
return new ContentValues();
}
}
Here you just call values() on your object and it retrieves the correct ContentValues.
Upvotes: 2