Страницы

Поиск по вопросам

вторник, 10 декабря 2019 г.

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

#java #android #mvp


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

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

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

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

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

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

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

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

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


Ответы

Ответ 1



Подходов здесь может быть несколько, и ещё несколько если использовать иные архитектурные паттерны. Я приму вашу вводную, как правило, буду отвечать отталкиваясь от MVP который вы частично описали, без CleanArchitecture Ваша задача больше похожу на организацию Local и Remote Storage, те организацию внутреннего(локального) и удаленного хранилища, а не проблема с архитектурой. Те это всё внутренняя организация Model(а она бывает очень разной). Первым делом я бы советовал организовать логику смены сети прямо в модели. Такой подход можете значительно увеличить скорость приложения, управляя удаленными и локальными источниками данных. Смотря на ваше описание проще сделать прямо наоборот те вы показываете всегда сохраненные(или закэшированные данные), из LocalStorage, если их нет(или другое условие), делаете запрос через RemoteStorage, сохраняете (своя логика) в LocalStorage и показываете их, тем самым вы добьетесь того что ваше приложение будет стабильно работать в любых условиях сети и самое главное оффлайн. Я накидал быстрый пример для вас, чтоб было наглядней, как бы сделал я: в Presenter: model .getDataList() .subscribe(this::showDataList); в Model: public Single> 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> 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 dataList){ adapter.setDataList(dataList); } Смотрите даже в таком примере с руки, получилось довольно компактно и понятно, если использовать дополнительный слой например DataMapper, тогда всё сведется в 1 структуру Rx используя flitre, flatmap будет ещё проще организовывать сложную логику, ведь там ещё напрашивается кэширование. PS: писал без IDE мог сделать ошибки:)

Комментариев нет:

Отправить комментарий