私のAndroidアプリケーションでは、非常によく似たクラスがあります。FooA
とFooB
と呼びましょう。これらのクラスのそれぞれについてJavaで静的ファクトリメソッドと定数を使って生成
、私はテーブルの列の定数を含むスキーマのクラスを持っている - FooASchema
とFooBSchema
:
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 = ...
}
両方FooA
とFooB
作成するために私を可能にし、静的なファクトリメソッドを持っていますそれらは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, ...);
}
最後に、私はテーブルからデータを取得するために使用する2つの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
それを持つことはできませんサブクラスを実装できます。
この方法で静的ファクトリメソッドを呼び出すにはどうすればよいですか?
これに近づき、コードの重複を減らす良い方法はありますか?あなたがするパラメータ化された型を使用することはできません、ジェネリック医薬品で
fooAs.add(FooA.from(cursor));
:あなたはクラスの静的メソッドを使用し、form()
工場を呼び出すために、クラスのインスタンスを使用していない、あなたの実際のコードで
は、このためのフレームワークやライブラリを使用することを検討してください。あなたがしたいことは、そうすることができません。ジェネリックはインスタンスでのみ動作します。タイプではありません。工場でのこのアプローチを考えてみてください。 – tynn