0

getTable() と getColumns() の 2 つの抽象メソッドを持つデータベース レコードを表す抽象 Record クラスがあります。次に、Record を拡張する Customer クラスを作成し、このクラスにこれらの抽象メソッドを実装します。

すべての顧客のリストを取得する方法を見つけようとしていますが、メソッドをできるだけ再利用可能に保つため、getAllCustomers() メソッドよりも getAllRecords(Record record) メソッドを使用したいと思います。

これが私がこれまでに持っているものです。抽象的で、渡されたクラスのインスタンスを作成する必要があるため、新しい Record() オブジェクトを作成できません。

//i'd like to do something like this to get all of the Customers in the db 
// datasource.getAllRecords(new Customer());

public List<Record> getAllRecords(Record record) {
    List<Record> records = new ArrayList<Record>();

    Cursor cursor = database.query(record.getTable(),
        record.getColumns(), null, null, null, null, null);

    cursor.moveToFirst();
    while (!cursor.isAfterLast()) {
      Record record = cursorToRecord(cursor, record);
      records.add(record);
      cursor.moveToNext();
    }
    // Make sure to close the cursor
    cursor.close();
    return records;
  }

  private Record cursorToRecord(Cursor cursor, Record record) {


    Record record = new Record(); <-- somehow clone a new instance of the record that was passed in

    record.setId(cursor.getLong(0));
    record.setValue("aKey",cursor.getString(1));
    return record;
  }

Record のサブクラスごとに個別のファクトリ クラスを用意する代わりに、ある種の RecordRegistry オブジェクトを用意することは理にかなっているでしょうか?

class RecordRegistry{

    private static final List<Record> RECORDS;

    static {
            final List<Record> records = new ArrayList<Record>();
            records.add(new Customer());
            records.add(new Company());

            RECORDS = Collections.unmodifiableList(records);
    }

    public List<Record> allRecords(){

        return RECORDS;
    }

    public Record buildRecord(Class cClass){

        String className = cClass.getName().toString();

        if(className.equalsIgnoreCase("customer")){
            return new Customer();
        }else if(className.equalsIgnoreCase("company")){
            return new Company();
        }
        return null;
    }
}
4

4 に答える 4

1

RecordのすべてのサブクラスにRecord引数なしのコンストラクターがある場合は、 のクラスを取得できます。

Record newRecord = record.getClass().newInstance();

オブジェクト自体の代わりにクラスを渡すことができることに注意してください。

適切なクラスのインスタンス化を担当するファクトリを渡すこともできます。

interface RecordFactory {
    Record create();
}

class CustomerFactory implements RecordFactory {
    Record create() {
        return new Customer();
    }
}

public List<Record> getAllRecords(RecordFactory factory) {
    ...
    for(...) {
        ...
        Record record = factory.create();
        ...
    }
    ...
}
于 2013-04-19T13:47:06.950 に答える
0

奇妙な使用例。メソッドをcursorToRecord抽象化します。これにより、ロジックが各クラスにプッシュされ、Cursor.

public abstract Record cursorToRecord(Cursor cursor, Record record);
于 2013-04-19T13:32:04.513 に答える
0

反射はどうですか?

Record newRecord = record.getClass().newInstance();
于 2013-04-19T13:47:11.743 に答える
0

Q に直接回答するわけではありませんが、コンテンツ プロバイダーに関する Android ガイド ( https://developer.android.com/guide/topics/providers/content-providers.html ) をご覧ください。それらは、他の利点の中でも特に柔軟なデータアクセスを可能にします。最初の学習とセットアップの努力に値することがわかりました(特にローダーと一緒に使用する場合)

于 2013-04-19T13:39:46.417 に答える