[英]How to call certain methods and return certain objects based on class type
Normally I try to use polymorphism to avoid using things like instanceof
, and I don't like using ORM frameworks because they often cause me a lot more headache than they're worth, so I tried to make my own database class with simple features. 通常我尝试使用多态来避免使用像instanceof
这样的东西,我不喜欢使用ORM框架,因为它们经常让我比他们的价值更令人头痛,所以我尝试用简单的功能创建自己的数据库类。
Some of you are probably giggling, "See, ORMs exist for a reason, don't roll your own!" 你们中的一些人可能在咯咯地笑,“看,ORM存在是有原因的,不要自己动手!” but I'm not trying to make a full-blown ORM; 但我不是想要制作一个完整的ORM; just something lightweight for my specific use that does what I need (cue more giggling, I know). 只是为我的特定用途轻量级的东西,做我需要的东西(提示更多咯咯笑,我知道)。
Right now I am hitting this issue: 现在我正在解决这个问题:
Normally when doing a select statement from an SQLiteDatabase when creating objects from the data tables, you use a Cursor
object, iterate over the records, and instantiate an object in the loop. 通常,在从数据表创建对象时从SQLiteDatabase执行select语句时,可以使用Cursor
对象,遍历记录,并在循环中实例化对象。
Consider a Dog class that extends MyDatabaseClass. 考虑一个扩展MyDatabaseClass的Dog类。
Is it considered bad practice to do something like this: 做这样的事情被认为是不好的做法:
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;
}
} }
So now if I want to get a list of Dogs I can do 所以现在,如果我想获得一份我可以做的狗列表
List<Dog> dogList = (List<Dog>) myDatabaseInstance.getList(Dog.class);
or make it a static method of the Dog class if need be. 或者如果需要的话,使它成为Dog类的静态方法。
Is this considered a valid approach, or is it considered dangerous to do that class comparison like this? 这被认为是一种有效的方法,还是像这样进行类比较被认为是危险的? I would have loved to use polymorphism somehow but I couldn't see any good way to do it on account of there being different fields for different classes with different constructors. 我本来希望以某种方式使用多态,但由于不同的类具有不同的构造函数存在不同的字段,我无法看到任何好的方法。
if you supply the data type, you can use generics. 如果提供数据类型,则可以使用泛型。
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;
}
How about it would look like this: 怎么样会这样:
List<Dog> dogList = new DogRepository(myDatabaseInstance).getList();
Its much better then if (clazz == Dog.class)
and you can use polymorphism having some BaseRepository with common methods. 它比if (clazz == Dog.class)
要好得多,你可以使用带有一些BaseRepository的多态来使用常用方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.