通常我尝试使用多态来避免使用instanceof
这样的东西,而且我不喜欢使用ORM框架,因为它们经常让我比他们更值得头疼,所以我试图用简单的功能创建我自己的数据库类。
你们当中有些人可能会咯咯地笑,"看,ORM存在是有原因的,不要自己动手!"但我并没有试图制作一个完整的ORM;只是为了我的具体用途而轻量级的东西,它可以满足我的需要(提示更多咯咯笑,我知道)。
现在我正在解决这个问题:
通常,在从数据表创建对象时从SQLiteDatabase执行select语句时,可以使用Cursor
对象,迭代记录,并在循环中实例化对象。
考虑扩展MyDatabaseClass的Dog类。
做这样的事情是不好的做法:
public Cursor getDogCursor(Cursor cursor) {
return database.query(Dog.TABLE_NAME, Dog.COLS, null, null, null, null, null);
}
public Cursor getCursor(Class<? extends MyDatabaseClass>) {
if (clazz == Dog.class) return getDogCursor();
//...
return null;
}
public Dog getDogFromCursor(Cursor cursor) {
String dogId = getLongFromColumnName(cursor, Dog._ID);
String dogName = getStringFromColumnName(cursor, Dog.COL_NAME);
return new Dog(dogId, dogName);
}
public MyDatabaseClass getDatabaseObjectFromCursor(Class<? extends MyDatabaseClass> clazz, Cursor cursor) {
if (clazz == Dog.class) return getDogFromCursor(cursor);
//...
return null;
}
public List<? extends MyDatabaseClass> getList(Class<? extends MyDatabaseClass> clazz) {
Cursor cursor = getCursor(clazz);
List<MyDatabaseClass> list = new ArrayList<>();
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
list.add(getDatabaseObjectFromCursor(clazz, cursor);
cursor.moveToNext();
}
cursor.close();
return list;
}
}
所以现在如果我想获得一份我可以做的狗的清单
List<Dog> dogList = (List<Dog>) myDatabaseInstance.getList(Dog.class);
或者如果需要的话,使它成为Dog类的静态方法。
这被认为是一种有效的方法,还是像这样进行类比较被认为是危险的?我本来喜欢以某种方式使用多态,但由于不同类的不同构造函数存在不同的字段,我无法看到任何好的方法。
答案 0 :(得分:1)
如果您提供数据类型,则可以使用泛型。
public <T extends MyDatabaseClass> List<T> getList(Class<T> clazz) {
Cursor cursor = getCursor(clazz);
List<T> list = new ArrayList<>();
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
//noinspection unchecked
list.add((T) getDatabaseObjectFromCursor(clazz, cursor));
cursor.moveToNext();
}
cursor.close();
return list;
}
答案 1 :(得分:0)
它会是这样的:
List<Dog> dogList = new DogRepository(myDatabaseInstance).getList();
它比if (clazz == Dog.class)
要好得多,你可以使用带有一些BaseRepository和普通方法的多态。