POJO против курсоров в Android - PullRequest
33 голосов
/ 30 марта 2010

Я обычно склонен определять слой модели моих приложений, используя POJO, такие как Article, Comment и т. Д.

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

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

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

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

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

Любой ввод?

Ответы [ 4 ]

13 голосов
/ 30 марта 2010

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

12 голосов
/ 28 июня 2012

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

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

Эти немногие преимущества стоят некоторого стандартного кода, многие ошибки были устранены, поскольку инженеры-пользователи сами не обращаются к столбцам курсора. Мы по-прежнему используем класс CursorAdapter, но первая строка в методе bindView заключается в создании POJO с поддержкой Cursor из Cursor, и с тех пор код будет красивым.

Ниже приведен пример реализации, для инженеров-пользователей совсем несложно превратить непрозрачный курсор в четко определенный пользовательский объект, с этого момента его можно передавать и обращаться к нему, как к обычному 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();
    }

}
9 голосов
/ 30 марта 2010

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

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

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

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

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

2 голосов
/ 03 апреля 2014

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

, если вы не запрашиваете сотни строк, но затем, как часто вы делаете это в сравнении с удобством использования POJO, геттеров и сеттеров

...