有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

安卓在Java中使用静态工厂方法和常量进行泛化

在我的Android应用程序中,我有一些非常相似的类,我们把它们叫做FooAFooB

对于这些类中的每一个,我都有一个schema类,其中包含表FooASchemaFooBSchema列的常量:

public final class FooASchema {

    public static final String TABLE_NAME = "foo_a_table";
    public static final String COL_CATEGORY_ID = "category_id";
    public static final String COL_PROPERTY_A = "property_a";
    public static final String COL_PROPERTY_B = "property_b";
    // COL_PROPERTY_C = ...

}


public final class FooBSchema {

    public static final String TABLE_NAME = "foo_b_table";
    public static final String COL_CATEGORY_ID = "category_id";
    public static final String COL_OTHER_PROPERTY_A = "other_property_a";
    // COL_OTHER_PROPERTY_B = ...

}

FooAFooB都有一个静态工厂方法,使我能够使用Cursor创建它们:

public static FooA from(Cursor cursor) {
    int categoryId = cursor.getInt(cursor.getColumnIndex(FooASchema.COL_CATEGORY_ID));
    String propertyA = cursor.getString(cursor.getColumnIndex(FooASchema.COL_PROPERTY_A));
    String propertyB = cursor.getString(cursor.getColumnIndex(FooASchema.COL_PROPERTY_B));
    // int propertyC = ...

    return FooA(id, propertyA, propertyB, ...);
}


public static FooB from(Cursor cursor) {
    int categoryId = cursor.getInt(cursor.getColumnIndex(FooBSchema.COL_CATEGORY_ID));
    int otherA = cursor.getInt(cursor.getColumnIndex(FooASchema.COL_OTHER_PROPERTY_A));
    // String otherB = ...

    return FooB(id, otherA, otherB, ...);
}

最后,我有两个用于从表中检索数据的util类:

public final class FooAUtils {

    public static ArrayList<FooA> getFooAs(Context context, int categoryId) {
        ArrayList<FooA> fooAs = new ArrayList<>();

        Cursor cursor = MyDbHelper.getInstance(context).getReadableDatabase.query(
                FooASchema.TABLE_NAME,
                null,
                FooASchema.COL_CATEGORY_ID + "=?",
                new String[] {String.valueOf(categoryId)},
                null,
                null,
                null);
        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
            fooAs.add(FooA.from(cursor));
            cursor.moveToNext();
        }
        cursor.close();
        return fooAs;
    }

    // ...
}


public final class FooBUtils {

    public static ArrayList<FooA> getFooBs(Context context, int categoryId) {
        ArrayList<FooB> fooBs = new ArrayList<>();

        Cursor cursor = MyDbHelper.getInstance(context).getReadableDatabase.query(
                FooBSchema.TABLE_NAME,
                null,
                FooBSchema.COL_CATEGORY_ID + "=?",
                new String[] {String.valueOf(categoryId)},
                null,
                null,
                null);
        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
            fooBs.add(FooB.from(cursor));
            cursor.moveToNext();
        }
        cursor.close();
        return fooBs;
    }

    // ...
}

您可以看到FooA相关类和FooB相关类之间的大多数代码非常相似,尤其是在util类中,它们的代码几乎相同

我想尝试减少这种重复,我一直在尝试使用泛型(我读过关于它们的文章,但还没有在项目中使用它们)

例如,我希望能够有一个通用的util类。以下是我如何实现它的想法:

public final class FooUtils {

    public static <T> get(Context context, int categoryId) {
        ArrayList<T> items = new ArrayList<>();

        Cursor cursor = MyDbHelper.getInstance(context).getReadableDatabase.query(
                BaseSchema.TABLE_NAME,
                null,
                BaseSchema.COL_CATEGORY_ID + "=?",
                new String[] {String.valueOf(categoryId)},
                null,
                null,
                null);
        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
            items.add(T.from(cursor)); // ??
            cursor.moveToNext();
        }
        cursor.close();
    }

    // ...

}

其中:

public interface BaseSchema {

    public static final String TABLE_NAME; // can't make this abstract?

    public static final String COL_CATEGORY_ID = "category_id";

}

public final class FooASchema implements BaseSchema { ... }


public final class FooBSchema implements BaseSchema { ... }

但是正如你所看到的,我不能做T.from(cursor),我不能有一个抽象常量TABLE_NAME子类可以实现

我如何以这种方式调用静态工厂方法

有没有更好的方法来解决这个问题并减少代码重复


共 (0) 个答案