Одно важное различие, о котором вам нужно помнить, это то, что LiveData
знает, когда к нему присоединяется наблюдатель, и может немедленно выдать значение, если LiveData
готов. Например, если ваше представление отсоединено и повторно присоединено к той же модели представления из-за некоторого изменения конфигурации, LiveData
может немедленно выдать значение, и, следовательно, ваше представление может легко восстановить состояние. Вы не можете сделать это с интерфейсом, и лучшее, что вы можете сделать с интерфейсом, это проверять, является ли обработчик нулевым, каждый раз, когда вы вызываете обработчик, чтобы просто предотвратить сбой приложения.
Также ваши две точки:
- Не совсем понятно, что должен вызывать каждый элемент strng / enum. Вы можете дать им читаемые подсказки значения / имена, но это не похоже на
имя метода с правильными строками документации в любом случае
- Вы можете отправлять дополнительные аргументы в Bundles, но это не похоже на правильную сигнатуру метода с типами и т. Д.
Правильны, за исключением того, что и RxJava
, и LiveData
могут легко справиться с этими проблемами, потому что они являются проблемами проектирования, а не инструментами. Например, ваш Event
класс может выглядеть так:
class Event(event: String, data: Bundle)
Не делай этого. Лучший способ сделать:
abstract class Event()
class DoneThisEvent(how:How, when:Time): Event()
class DoneThatEvent(location:Location, withWho:Person): Event()
Кроме того, вы должны думать о зависимости между событиями. Другими словами, могут ли события «Я сделал это» и «Я сделал То» сосуществовать одновременно? Сравнение данной реализации LiveData
и ViewModelEventsHandler
не является справедливым, поскольку в реализации LiveData
предполагается, что эти два события не могут сосуществовать, а в реализации ViewModelEventsHandler
они могут. Давайте сравним оба сценария:
Если два события не могут сосуществовать
Тогда ваш пример LiveData
имеет смысл, но все же есть место для улучшения:
viewModel.iDidThisAndThat.observe(this, Observer { done ->
when(done) {
is DoneThisEvent -> handleViewModelDidThis(done.how, done.when) // Notice the automatic type casting
is DoneThatEvent -> handleViewModelDidThat(done.location, done.withWho)
}
})
Также проверьте ваш ViewModelEventsHandler
аналог.
viewModel.eventsHandler = ViewModelEventsHandler {
override fun viewModelDidThisAndThat(done: Event) {
when(done) {
is DoneThisEvent -> handleViewModelDidThis(done.how, done.when) // Notice the automatic type casting
is DoneThatEvent -> handleViewModelDidThat(done.location, done.withWho)
}
}
}
Как вы можете видеть, между ними нет никакой разницы, за исключением того, что с ViewModelEventsHandler
вам нужно вручную проверять ноль и обрабатывать присоединение / отсоединение обработчиков событий.
Если два события могут сосуществовать
Если два события независимы, то они должны наблюдаться независимо.
// In activity onCreate
viewModel.iDidThis.observe(this, Observer { doneThis ->
handleViewModelDidThis(doneThis.how, doneThis.when)
})
viewModel.iDidThat.observe(this, Observer { doneThat ->
handleViewModelDidThat(doneThat.location, doneThat.withWho)
}
// In your ViewModel
val iDidThis: LiveData<DoneThisEvent>
val iDidThat: LiveData<DoneThatEvent>
Эта реализация LiveData
не должна выглядеть уродливее или менее управляемой, чем ее ViewModelEventsHandler
аналог:
viewModel.eventsHandler = ViewModelEventsHandler {
override fun viewModelDidThis(String how, Date when) {
handleViewModelDidThis(how, when)
}
override fun viewModelDidThis(Location where, List<Friends> withWho) {
handleViewModelDidThat(where, withWho)
}
}