34

私は通常、Article、Comment などの POJO を使用して、アプリのモデル レイヤーを定義する傾向があります。

ListViews の 1 つのアダプターに AlphabetIndexer を実装しようとしていました。現在、このアダプターは記事のコレクションを受け入れます。これは通常、SQLiteDatabase のラッパーから取得します。

AlphabetIndexer コンストラクターのシグネチャは次のとおりです。

public AlphabetIndexer (Cursor cursor, int sortedColumnIndex, CharSequence alphabet)

これは Collection などを受け入れず、Cursor だけを受け入れるので、モデルのオブジェクトを作成するのではなく、データベースから返された Cursor を使用するだけでよいのではないかと思いました。

問題は、 POJOのコレクションでデータを表現するか、アプリ全体でカーソルを操作するか、どうすればよいかということです。

入力はありますか?

4

4 に答える 4

13

私は同様の問題に遭遇しました。現在、私はPOJOから離れる傾向があります。ただし、必要Cursorに応じて、POJOのコレクション用に独自のインターフェイスを作成できることに注意してください。

于 2010-03-30T13:33:24.753 に答える
12

私は、カーソルを利用した POJO クラスを作成するのが好きです。Cursor-backed POJO クラスには、Cursor を受け取るコンストラクターがあり、次の利点があります。

  • 適切なコンテンツ タイプを返す使いやすいゲッター。インデックスを取得してデータベース内のデータのタイプを記憶するよりもはるかに優れています。
  • オブジェクト指向プログラミングのあるべき方法と同様に、他のゲッターからの結果を計算するゲッター メソッド
  • ゲッターの戻り値は列挙型にすることができます!

これらのいくつかの利点は、いくつかの定型コードの価値があります。ユーザー エンジニアがカーソル列自体にアクセスしていないため、多くのバグが回避されています。CursorAdapter クラスは引き続き使用しますが、bindView メソッドの最初の行は、Cursor から Cursor をサポートする POJO を作成することであり、それ以降のコードは美しいものになります。

以下は実装例です。ユーザー エンジニアが不透明なカーソルを明確に定義されたユーザー オブジェクトに変換するのは簡単です。その時点から、バッキング カーソルが閉じられていない限り、通常の POJO と同じように渡してアクセスできます。SmartUserCursor は、カーソルがアクセスされる前にカーソル位置が記憶され、復元されるようにするために作成した特別なクラスであり、カーソル列のインデックスも格納するため、検索が高速になります。

例:

public class User {

    private final SmartUserCursor mCursor;

    public User(SmartUserCursor cursor, int position) {
        mCursor = new SmartUserCursor(cursor, position);
    }

    public long getUserId() {
        return mCursor.getLong(SmartUserCursor.Columns.userId);
    }

    public UserType getType() {
        return UserType.valueOf(mCursor.getString(SmartUserCursor.Columns.type));
    }

    public String getFirstName() {
        return mCursor.getString(SmartUserCursor.Columns.firstName);
    }

    public String getLastName() {
        return mCursor.getString(SmartUserCursor.Columns.lastName);
    }

    public final String getFullName() {
        return getFirstName() + " " + getLastName();
    }

    public static User newUserFromAdapter(BaseAdapter adapter, int position) {
        return new User((SmartUserCursor)adapter.getItem(position), position);
    }

    public static User newUserBlocking(Context context, long UserId) {
        Cursor cursor = context.getContentResolver().query(
                Users.CONTENT_URI_CLIENT,
                Users.DEFAULT_USER_PROJECTION,
                Users.Columns.USER_ID+"=?",
                new String[] {String.valueOf(UserId)},
                null
        );

        if (cursor == null || !cursor.moveToFirst()) {
            throw new RuntimeException("No User with id " + UserId + " exists");
        }

        return new User(new SmartUserCursor(cursor, Users.DEFAULT_USER_PROJECTION), -1);
    }

    public final void closeBackingCursor() {
        mCursor.close();
    }

}
于 2012-06-27T23:32:24.950 に答える
9

エンティティ オブジェクト (POJO) に 1 票。特にUIレイヤーにカーソルを渡すことは、私にはとても間違っていると感じています(Android SDKがそのようにすることを暗示しているかどうかにかかわらず)。通常、UI を設定する方法はいくつかありますが、私はカーソルを直接使用する方法を避ける傾向があります。たとえば、カスタム リスト ビューにデータを入力するために、SimpleAdapter を使用しList<? extends Map<String, ?>>、SimpleAdapter のコンストラクターとしてコレクション オブジェクト自体の表現を返す機能を与えます。

各テーブルがエンティティ オブジェクトによってラップされ、そのエンティティに関連付けられた CRUD 操作を処理するプロバイダー クラスを持つパターンを使用します。必要に応じて、コレクションの拡張機能が必要な場合は、それらもラップします (つまりEntityItems extends ArrayList<EntityItem>、.

個人的な好み以外の最大の理由は、この種のコードを UI からできるだけ遠くに隠したいからです。

String something = cursor.getString(cursor.getColumnIndex(COLUMN_NAME_CONSTANT));

この種のコードが UI レイヤーにインラインで表示されている場合は、通常、さらに悪いコードがすぐ近くに潜んでいることが予想されます。私は企業の世界で大規模なチームでの作業に多くの時間を費やしてきたのかもしれませんが、正当なパフォーマンス上の懸念がない限り、または表現力が企業のやり過ぎである十分に小さなタスクでない限り、読みやすさを好みます。

于 2010-03-30T14:11:36.543 に答える
2

答えは4歳です。これで、より多くのものを処理するのに十分な CPU パワーが得られたと思います。私の考えは、POJO と ArrayList のみで動作することです。CursorLoader を拡張して、カーソルをバックグラウンドで POJO にマップし、arraylist をアクティビティに配信します。

何百もの行をクエリしない限り、POJO、ゲッター、セッターを使用することの良さに対して、どれくらいの頻度でそれを行っていますか

于 2014-04-02T22:50:09.747 に答える