Живые списки с GreenDAO

Многие любят Realm за реактивность, а GreenDAO — за маленький размер библиотеки. Мне реактивность Realm показалась неадекватной, поэтому я выбрал GreenDAO для нового проекта. Вместе с DiffUtil мне удалось создать список на основе RecyclerView, который обновляется в реальном времени. Это выглядит лучше, чем в Realm, потому что вместо notifyDataSetChanged используются notifyItemChanged и DiffUtil.dispatchUpdatesTo(adapter).

Библиотека пока сырая. Кодревью, багрепорты и предложения приветствуются.

Интерфейс

Какой интерфейс и как этим пользоваться:

/**
 * Интерфейс, представляющий реактивный слой данных (DAL)
 * @param T тип моделей
 * @param QUERY тип запроса (чтобы не привязывать интерфейс к Query из GreenDAO)
 */
public interface LiveDataLayer {

    T get(Long id);
    void save(T t);
    void remove(T t);

    void subscribeOnSingle(Long pk, SingleSubscriber subscriber);
    void unsubscribe(SingleSubscriber subscriber);

    void subscribeOnList(QUERY query, BaseListSubscriber subscriber);
    void unsubscribe(BaseListSubscriber subscriber);

    /**
     * Подписчик, который ждёт обновлений одного объекта
     */
    interface SingleSubscriber {
        /**
         * Запись изменилась
         * @param newT    обновлённая запись
         */
        void onChange(T newT);
    }

    /**
     * Подписчик, который ждёт обновлений списка
     */
    interface ListSubscriber extends BaseListSubscriber {
        /**
         * Произошло структурное изменение: хотя бы одна запись была удалена или вставлена
         * @param newList           новый список
         * @param newIds            новые IDы
         * @param changedItemIds    IDы изменённых записей
         */
        void onStructuralChange(List newList, long[] newIds, Set changedItemIds);
    }
    /**
     * Подписчик, который ждёт обновлений списка и хочет выполнить какие-то вычисления в фоне по этому поводу
     */
    interface ListSubscriberWithPayload extends BaseListSubscriber {
        void onStructuralChange(List newList, long[] newIds, Set changedItemIds, PL payload);
        PL calculatePayload(List newList, long[] newIds, Set changedItemIds);
    }
    /**
     * Оба подписчика на списки наследуют этот интерфейс
     */
    interface BaseListSubscriber {
        /**
         * Произошло неструктурное изменение (UPDATE)
         * @param newList           новый список
         * @param changedItemIds    IDы изменённых записей
         */
        void onChange(List newList, Set changedItemIds);
    }

    /**
     * Модели должны реализовать этот интерфейс
     */
    interface WithId {
        Long getId();
    }

}

Комментарии к статье