Как восстановить модельное состояние в MVP? - PullRequest
0 голосов
/ 07 марта 2019

Описание приложения

Я впервые пытаюсь реализовать приложение для Android с MVP, в котором отображается сообщение (взятое из пула сообщений), и оно изменяется, когда пользователь нажимает на экран.,Как только все сообщения будут отображены, процесс начнется заново (в том же порядке сообщений).Требуется отобразить то же сообщение, если приложение закрыто / повторно открыто.Таким образом, мы должны реализовать некоторые механизмы хранения / восстановления состояния в модели MVP.

Вот базовая демонстрация приложения:

enter image description here

MVP Design

Я реализовал этот MVP дляэто приложение выглядит следующим образом:

  1. Модель позаботится о что будет следующим сообщением (оно реализует состояние приложения).
  2. Presenter решает , когда запрашивать следующее сообщение (для обновления состояния), в зависимости от полученных событий от пользователя (через представление).
  3. Просмотр решает как показывать фактическое сообщение и передает события от пользователя (щелчки на экране) докладчику.Кроме того, поскольку View также является MainActivity, он заботится о создании реализаций Presenter и Model.Наконец, сохраняет состояние модели (как Parcelable) с onSaveInstanceState (а также восстанавливает его).

Некоторый код

(Частичное) Просмотр реализации:

class MainActivity : AppCompatActivity(), ViewMVC {

    private lateinit var presenter: Presenter
    private var model: Model? = CircularModel(LinkedList<State>(Arrays.asList(
            State("First"),
            State("Second"),
            State("Third")

    )))

    override fun onCreate(savedInstanceState: Bundle?) {
        if (savedInstanceState != null) {
            model = savedInstanceState.getParcelable("model")
        }

        presenter = PresenterImpl(this, model!!)
    }

    override fun onSaveInstanceState(outState: Bundle?) {
        outState?.putParcelable("model", model!!)
        super.onSaveInstanceState(outState)
    }

(Частичное) Реализация модели:

@Parcelize
class CircularModel constructor(var states: @RawValue Deque<State>?) : Model, Parcelable {

    override fun getModelState(): State {
        return states!!.peekFirst()
    }

    override fun getModelNextState(): State {
        // Black magic happening here!
        return getModelState()
    }
}

Проблема / Мой вопрос

Поскольку Presenter и Model должны быть «независимыми от Android», сохранение состояния приложения (т. Е. Объекта Model) обеспечивается представлением.Однако это нарушает принцип, когда представление не знает модель. У меня вопрос: как сохранить объект Model, если View не знает о его реальной реализации?Каков наилучший способ обработки состояния модели в этом сценарии?

Фактическим решением может быть написание кода для сериализации модели в самой модели и сохранение его для каждого getNextState(),но это будет означать использование вызовов Android в модели (и снижение ее тестируемости).

1 Ответ

1 голос
/ 07 марта 2019

Вы должны использовать другой механизм персистентности.OnSaveInstanceState () действительно используется в ситуациях, когда ОС требуется восстановить состояние пользовательского интерфейса из-за таких изменений, как конфигурация / ориентация.Это не механизм хранения общего назначения.

Модель - это правильное место для хранения данных, и правильно, что вы должны стараться сохранять модель как можно более независимой от Android.Что вы можете сделать, это определить интерфейс, который представляет ваши требования к постоянству:

interface SampleRepo{ 
   fun saveData(...)
   fun getData(...)
}

Тогда ваш предпочтительный механизм сохранения (например, SharedPreferences, SQlite и т. Д.) В классе реализует этот интерфейс.Вот где ваши специфические вещи для Android будут скрыты.

class SharedPrefRepo : SampleRepo{
   override fun saveData(...)
   override fun getData(...)
}

В идеале вам понадобится какой-нибудь механизм инъекции, чтобы вы могли внедрить экземпляр вышеупомянутого в класс вашей модели (например, Dagger).Для этого требуется еще какой-нибудь сантехнический код, но это цена слабой связи.Для более простого приложения, такого как то, что вы делаете, все это излишне.Но если вы пытаетесь изучить правильную архитектуру приложений Android и слабую связь, то стоит изучить, как это сделать правильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...