sockeqwe / mosby

A Model-View-Presenter / Model-View-Intent library for modern Android apps
http://hannesdorfmann.com/mosby/
Apache License 2.0
5.49k stars 841 forks source link

ViewModel - MVVM #71

Closed sockeqwe closed 7 years ago

sockeqwe commented 9 years ago

We should support MVVM pattern as well (as addition to MVP - not replacement). The main question is, whether we should use new Android's data binding API or RxAndroid. We can expect that RxAndroid will make some big progress next weeks https://github.com/ReactiveX/RxAndroid/issues/172

I guess waiting until a stable databinding 1.0 and RxAndroid 1.0 version is available is a good idea to make a final discussion which way to go. Probably, we could implement ViewModel genericly so that we can use is for both frameworks.

also MVVMC seems to be a valid pattern, but that may not belong in this library: http://skimp-blog.blogspot.de/2012/02/mvvm-is-dead-long-live-mvvmc.html

Further discussion with other devs (please don't comment on google+ , use github this issue here for suggestions, recommandations and so on) https://plus.google.com/+HannesDorfmann/posts/DsukugwZsbG

Handling screen orientation changes is a MUST HAVE

IgorGanapolsky commented 9 years ago

Data Binding gets rid of the need for Butterknife. It also has Observable Objects - which automatically update your Views when data changes. It also makes your ViewHolder code simpler, by binding all the Views for you implicitly. How could this be a bad thing?

suarezjulian commented 9 years ago

Agree with Igor on this one.

Data Binding is a great thing, it gets rid of the need of Butterknife, is/will be officially supported, but I also thing that integrating this in the right way in mosby would not be an easy task

On Fri, Jul 17, 2015 at 9:52 AM, Igor Ganapolsky notifications@github.com wrote:

Data Binding gets rid of the need for Butterknife. It also has Observable Objects - which automatically update your Views when data changes. It also makes your ViewHolder code simpler, by binding all the Views for you implicitly. How could this be a bad thing?

— Reply to this email directly or view it on GitHub https://github.com/sockeqwe/mosby/issues/71#issuecomment-122300025.

sockeqwe commented 9 years ago

misunderstanding: im just saying that Im not sure which databinding engine should be used:

Androids databinding plugin

OR

RxAndroid / RxJava

That has to be evaluated

Julián Suárez notifications@github.com schrieb am Fr., 17. Juli 2015 16:59:

Agree with Igor on this one.

Data Binding is a great thing, it gets rid of the need of Butterknife, is/will be officially supported, but I also thing that integrating this in the right way in mosby would not be an easy task

On Fri, Jul 17, 2015 at 9:52 AM, Igor Ganapolsky <notifications@github.com

wrote:

Data Binding gets rid of the need for Butterknife. It also has Observable Objects - which automatically update your Views when data changes. It also makes your ViewHolder code simpler, by binding all the Views for you implicitly. How could this be a bad thing?

— Reply to this email directly or view it on GitHub https://github.com/sockeqwe/mosby/issues/71#issuecomment-122300025.

— Reply to this email directly or view it on GitHub https://github.com/sockeqwe/mosby/issues/71#issuecomment-122302546.

Nilzor commented 9 years ago

Don't forget that Butterknife itself is a kind of databinding, and Jake Wharton acknowledges this himself by making the naming relfect that in v7.0 and in this comment on reddit: https://www.reddit.com/r/androiddev/comments/3beofj/butterknife_700_released/cslilzp. I believe it lacks two-way databinding as of now, but maybe he's got plans to improve that as well now that he sees the competition sharpening (edit: no, don't think so: https://github.com/JakeWharton/butterknife/issues/269)? So I believe you have 32 options.

Anyway, my money is on Google's solution right now because:

PS: From looking at your examples, do you agree that your ViewState equals the ViewModel in MVVM terms? (I haven't used your library in a production system yet so my experience is limited, but I do like what I see and I very much appreciate your initiative with this issue! :) )

sockeqwe commented 9 years ago

@Nilzor thanks for sharing your knowledge! Butterknife is an alternative, but Butterknife requires R.java file for getting view ids. I would like to avoid having Android dependencies in the ViewModel in favor to write unit tests that can run on jvm (rather than a real android device by using InstrumentationTests).

I agree that using a first party solution (android's data binding) would be a better choice regarding maintenance, correctness, further development etc.

An advantage of RxJava is that we don't have to worry about lifecycle, since the view simply unsubscribes itself in Activity.onDestroy(). So there is no need to have a method we have to invoke to tell the ViewModel that we should cancel any ongoing async. background threads, because the view has been destroyed. I'm not sure how this could be done easily with android's data binding framework. I guess some kind of cancel command is needed for something like this. Any thoughts on that?

ViewState is a "special" class to hold the UI's state during screen orientation changes. So yes, in MVVM that would be part of ViewModel I guess. IMHO : ViewModel = Presenter + ViewState + DataBinding

Nilzor commented 9 years ago

Regarding cancellation: I'm not sure you'd always need that. Depends on the use case.

Scenario 1: HTTP call to service Fragment with retainInstance=true rotates mid-transaction. No problem - if the result arrives mid-rotation (after onPause and before onResume), the data will be set to the idle view model and bound when resuming. If it arrives after rotation, the data will be bound if the fields are of type ObservableField

Scenario 2: HTTP call to service Fragment with retainInstance=false. Device rotates before result arrives. The data binding framework will automatically unsubscribe from the ObservableField-objects, so you won't get any exceptions but some CPU cycles are wasted processing the result and the request will restart.

Scenario 3: Long-running background thread continuously producing data for the view. In this case you'd need cancellation, but I'd say it's out of the scope of a framework.

Maybe a framework could/should support a perfect implementation of scenario 2 where the response of the initial request is processed and rendered in the second instance of the view. I'm not sure.

shism2 commented 9 years ago

Couldn't RXandroid AND android Databinding just be combined into mvp mosby framework? It would be something like MVVP

IgorGanapolsky commented 9 years ago

@shism2 What does RXjava have to do with Data Binding? On Aug 15, 2015 6:19 PM, "shism2" notifications@github.com wrote:

Couldn't RXandroid AND android Databinding just be combined into mvp mosby framework? It would be something like MVVP

— Reply to this email directly or view it on GitHub https://github.com/sockeqwe/mosby/issues/71#issuecomment-131456516.

sockeqwe commented 9 years ago

@shism2 What is the difference between MVVP and MVVM?

ersin-ertan commented 9 years ago

Relevant video on Google's Databinding plugin. Goto 42:00 to hear mention of Presenter and ViewModel.

Some key points about threading:

vladp commented 8 years ago

Hello, not a user of mosby yet. But, if it counts, I would vote for mosby to leverage the new Google's databinding

I would say that as far as functional intent, and original sockeqwe question -- I feel that Google's databinding is more analogous to Jake Wharton's RxBinding http://github.com/JakeWharton/RxBinding

To expand a bit more, I am not sure that Google's databinding is flexible enough (or intended to) bind/observe IO completion events (eg http fetches, or SQLLite query completion) to Mosby's MvpPresenter.

In fact, in an app I am building -- I intend to leverage, in some activities, React-Native as well.

So I am basically ending up with the following scheme Model<--rxAndroid-->Presenter<--G.Databiding-->NativeUI(layout/xyz.xml) Model<--rxAndroid-->Presenter<--ReactNativeBridge--->ReactUI (abc.js) So I am ending up with 2 binding tools for the UI layer, while with sticking with rxAndroid for non-UI stuff. There is also a new library that hides underneath ReactNativeBridge stuff, and I might end up leveraging that (still learning though) http://github.com/Kudo/RxRNBridge

sockeqwe commented 7 years ago

Ditched MVVM in favor of Model-View-Intent; sample is available. Pre release (alpha release of Mosby 3.0.0-alpha1) coming soon.