简体   繁体   English

如何调用某些方法并根据类类型返回某些对象

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM