Как правильно оформить модель в MVP?

210
22 июля 2018, 02:00

В паттерне MVP за данные отвечает модель, то есть, в ней мы реализуем все, что связанно с получением данных.

Если приложение работает с сервером, то в модели описаны все методы для работы с сервером.

Если модель работает с BD, то в модели описаны все методы для работы с ней.

Но если приложение использует и сервер и BD

Если приложение в оффлайн, то используем то что есть в BD. Если онлайн, то делаем обращение к серверу.

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

Как это правильно организовать?

1) динамически менять модели в зависимости от оффлайн или онлайн?

2) создать модель, в которой будут имплементированны методы и для работы с сервером, и для BD?

Answer 1

Подходов здесь может быть несколько, и ещё несколько если использовать иные архитектурные паттерны. Я приму вашу вводную, как правило, буду отвечать отталкиваясь от MVP который вы частично описали, без CleanArchitecture

Ваша задача больше похожу на организацию Local и Remote Storage, те организацию внутреннего(локального) и удаленного хранилища, а не проблема с архитектурой. Те это всё внутренняя организация Model(а она бывает очень разной). Первым делом я бы советовал организовать логику смены сети прямо в модели. Такой подход можете значительно увеличить скорость приложения, управляя удаленными и локальными источниками данных. Смотря на ваше описание проще сделать прямо наоборот те вы показываете всегда сохраненные(или закэшированные данные), из LocalStorage, если их нет(или другое условие), делаете запрос через RemoteStorage, сохраняете (своя логика) в LocalStorage и показываете их, тем самым вы добьетесь того что ваше приложение будет стабильно работать в любых условиях сети и самое главное оффлайн. Я накидал быстрый пример для вас, чтоб было наглядней, как бы сделал я:

в Presenter:

    model
         .getDataList()
         .subscribe(this::showDataList);

в Model:

public Single<ArrayList<Data>> getDataList(){
    if (localStorage.isFilled())
        return localStorage
            .getDataList()
            .subscribeOn(schedulers.io())
            .observeOn(schedulers.ui());
    else
        return remoteStorage
            .getDataList()
            .flatMap(localStorage::save)
            .subscribeOn(schedulers.io())
            .observeOn(schedulers.ui());
}

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

public Single<ArrayList<Data>> updateDataList(){
    if (isInternetConnection)
        return remoteStorage
                .getDataList()
                .flatMap(localStorage::save)
                .subscribeOn(schedulers.io())
                .observeOn(schedulers.ui());
    else
        return localStorage
                .getDataList()
                .subscribeOn(schedulers.io())
                .observeOn(schedulers.ui());
}

в View:

private void showDataList(ArrayList<Data> dataList){
    adapter.setDataList(dataList);
}

Смотрите даже в таком примере с руки, получилось довольно компактно и понятно, если использовать дополнительный слой например DataMapper, тогда всё сведется в 1 структуру Rx используя flitre, flatmap будет ещё проще организовывать сложную логику, ведь там ещё напрашивается кэширование.

PS: писал без IDE мог сделать ошибки:)

READ ALSO
error: cannot find symbol method openConnection()

error: cannot find symbol method openConnection()

Хочу в Android Studio получить ответ от сайта, но проблема в том, что не может найти метод openConnection, ибо часть кода брал с старых APIНа что его можно...

236
Statement and PreparedStatement

Statement and PreparedStatement

Здравствуйте объясните пожалуйста разница между Statement и PreparedStatement в каком случае нужно использовать Statment и в каком случае PreparedStatment если не сложно...

223
Поле и/или переменная? Вот в чем вопрос. (Java)

Поле и/или переменная? Вот в чем вопрос. (Java)

По ходу моего обучения языка java термин "поле" не дает мне покояЯ ни в книгах, ни в сети не нашел понятного объяснения этого явления

172
JavaFx как добавить DirectoryChooser?

JavaFx как добавить DirectoryChooser?

Есть следующий класс:

209