POJO против курсоров в Android

Обычно я обычно определяю слой модели своих приложений с помощью POJO, например, статьи, комментария и т.д.

Я собирался реализовать AlphabetIndexer в адаптере одного из моих списков ListView. Прямо сейчас этот адаптер принимает коллекцию статей, которую я обычно получаю из своей обертки вокруг базы SQLiteDatabase.

Подпись конструктора AlphabetIndexer выглядит следующим образом:

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

Поскольку это не принимает коллекцию или что-то подобное, просто курсор, мне стало интересно: может быть, я не должен создавать объекты для своей модели и просто использовать курсоры, возвращаемые из базы данных?

Итак, вопрос, я думаю: что мне делать, представлять данные с коллекциями POJO или просто работать с курсорами во всем моем приложении?

Любой вход?

Ответ 1

У меня возникли аналогичные проблемы. Прямо сейчас я уклоняюсь от ПОЖО. Обратите внимание, однако, что вы можете создать свой собственный интерфейс Cursor для коллекции POJO, если вы этого захотите.

Ответ 2

Мне нравится создавать классы POJO с поддержкой курсора. Класс POJO, поддерживаемый курсором, имеет конструктор, который использует курсор и предоставляет следующие преимущества:

  • Простые в использовании геттеры, которые возвращают правильный тип контента, намного лучше чем получение индексов и необходимость запоминать тип данных в базы данных
  • Методы Getter, которые вычисляют их результаты от других геттеров, точно так же, как программирование OO должно быть
  • Возвращаемые значения Getter могут быть перечислениями!

Эти несколько преимуществ заслуживают некоторого кода шаблонов, многие многие ошибки были предотвращены теперь, когда пользовательские инженеры не получают доступ к столбцам самих столбцов. Мы по-прежнему используем класс CursorAdapter, но первая строка в методе bindView состоит в том, чтобы создать 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();
    }

}

Ответ 3

Один голос для объектов сущностей (POJO). Передача курсоров вокруг, особенно на слой пользовательского интерфейса, мне так не нравится (независимо от того, подходит ли Android sdk). Обычно существует несколько способов заполнения пользовательского интерфейса, и я стараюсь избегать тех, которые непосредственно используют курсоры. Например, чтобы заполнить списки пользовательского списка, я использую SimpleAdapter и даю объектам моей коллекции возможность вернуть представление себя как List<? extends Map<String, ?>> для конструктора SimpleAdapter.

Я использую шаблон, где каждая таблица обертывается объектом сущности и имеет класс поставщика, который обрабатывает мои операции CRUD, связанные с этим объектом. Необязательно, если мне нужна расширенная функциональность для коллекций, я тоже их обертываю (т.е. EntityItems extends ArrayList<EntityItem>). У провайдера есть базовый класс, который я передаю ссылку на класс DbAdapter, который делает тяжелый подъем вокруг db.

Самая большая причина, кроме личных предпочтений, заключается в том, что я хочу скрыть этот код как можно дальше от моего интерфейса:

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

Если я вижу такой тип кода в слое пользовательского интерфейса, я обычно ожидаю увидеть гораздо хуже, скрываясь за углом. Возможно, я просто потратил слишком много времени в корпоративном мире, работая над большими командами, но я предпочитаю читаемость, если нет законной проблемы с производительностью или если это достаточно маленькая задача, в которой выразительность - это просто излишний бизнес.

Ответ 4

Ответы - 4 года. Я думаю, что теперь у нас достаточно мощности процессора, чтобы уйти с большим количеством вещей. Моя идея заключалась бы в работе только с POJO и ArrayLists; и расширение CursorLoader для отображения курсора в POJO в фоновом режиме и доведения до уровня arraylist;

если youre не запрашивает сотни строк, но затем, как часто вы делаете это против превосходства использования POJO, getters и seters