Android MVP — RxJava и модернизация — лучший подход

Я выясняю, как разработать приложение для Android, используя MVP, RxJava2 и модификацию.

В моем ведущем вот код:

public void loadData() {

    compositeDisposable.dataModelRepository.getDataList().subscribeOn(Schedulers.io())
            .observeOn(mainScheduler).subscribe(new Consumer<List<Data>>() {
        @Override
        public void accept(List<Data> dataList) throws Exception {
            if (!dataList.isEmpty())
                view.displayData(dataList);
            else
                view.displayEmpty();
        }
    }, new Consumer<Throwable>() {
        @Override
        public void accept(Throwable throwable) throws Exception {
            System.out.println(throwable.toString());
            view.displayError("boooom");
        }
    });
}

Интерфейс модернизации был определен следующим образом:

@GET("/fooURL")
Single<List<Data>> getDataList();

И репозиторий просто

public Single<List<Data>> getDataList() {
    return retrofitApi.getDataList();
}

И это работает нормально. Вопрос заключается в следующем: я намерен получать сетевые данные только тогда, когда данные недоступны локально, в БД.

Имея это в виду, правильно ли, что планировщики управляются в презентере? Или они должны управляться в репозитории?

Я предполагаю, что презентер — это правильное место, так как он создает поток, чтобы репозиторий мог выполнять свои действия последовательно (извлекать БД, если ничего, затем извлекать сеть/кэш; возвращать данные, где бы они ни были извлечены), и когда данные предоставлены, уведомить представление внутри метода accept Потребителя.

Это правильно? Или это надо делать по-другому?

Другой момент: как я могу протестировать репозиторий Mockito? Я имею в виду метод dataModelRepository.getDataList()? Не уверен, как сделать любое утверждение для отдельных объектов...

Заранее спасибо!


person Alex_ES    schedule 05.09.2017    source источник
comment
Взгляните на конкат. Это можно использовать для потребления первого наблюдаемого (локально), и если он не испускает элементы, он потребляет второй (сеть).   -  person Emanuel S    schedule 05.09.2017
comment
в MVP нет правильного пути. Люди делают то, что им подходит. Это все основано на мнении   -  person Tim    schedule 05.09.2017
comment
@EmanuelSeibold спасибо за совет!   -  person Alex_ES    schedule 05.09.2017
comment
@TimCastelijns согласен с вами, я просто хотел бы увидеть разные точки зрения. Как вы можете видеть, у этого подхода могут быть проблемы с модульным тестом, так как я не уверен, как мы можем проверить репозиторий... может быть, кто-то предложит что-то другое, что лучше подходит   -  person Alex_ES    schedule 05.09.2017
comment
к сожалению, это не место, чтобы спрашивать различные точки зрения. Вопросы, основанные на мнении, здесь не по теме   -  person Tim    schedule 05.09.2017


Ответы (1)


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

Один из способов добиться того, что вы описали, - это использовать оператор concat.

Observable<List<Data>> getData() {
    return Observable
        .concat(localRepository.getData(), remoteRepository.getData())
        .first();
}

Это попытается сначала получить данные из вашего локального репозитория, и если у него нет данных, он сделает сетевой запрос.

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

person Andrej Jurkin    schedule 07.09.2017
comment
Спасибо за совет, на самом деле я уже создал класс репозитория, то есть в настоящий момент выступает в роли прокси (получает запрос getData и отправляет запрос в сеть). Следующим шагом будет создание этого действия concat для первоначальной попытки извлечения из базы данных. Спасибо! - person Alex_ES; 08.09.2017