Good day you guys, I have some debate about MVVM w...
# android
s
Good day you guys, I have some debate about MVVM with my team/friends with 2 points: 1. Must use Databinding in XML to following architecture MVVM + databinding : Example :
Copy code
<data>
       <variable name="user" type="com.example.User"/>
   </data>
2. We should build XML to be pure , it mean does not include code because easier to management. debug, troubleshoot (Kotlin file for code and XML for UI). we should use
Databinding
for binding view to safety-reference. we still achieve the MVVM. How do you think about these points? Thanks.
d
ViewBinding is available for generated bindings without having to use DataBinding https://developer.android.com/topic/libraries/view-binding
👍 1
s
Thanks @Desmond Teo, but do you think we should have databinding in MVVM?
g
must have databinding in MVVM
Of course it’s not a requirement
☝️ 1
MVVM works with or without databindings, it’s strange argument. Discussion “should we use databindings” or not is another question
I didn’t get second point. Is it argument against databindings? If so I never really understand it, yes bad code can include more login in databinding layouts than necessary, but I don’t see how it argument against databindings, it’s actually very easy with bindings separate pure business logic from binding code and from work with views, I would say it’s a lot easier than without databindings, when cross borders is a lot easier. with data bindings it’s pretty hard to write any complex expression in layout. Actually your example with “User” variable is probaly a bad example, I wouldn’t recommend to use pure data classes as databinding models, it very soon be too limited, impossible to add custom logic there
s
@gildor Thanks for sharing, I have updated
must
to
should
. Second point: 1. Should use ViewBinding/Databinding for generated view from XML for type safety. 2. XML and code mix into the same file XML, someone see it hard to management in multiple modules, troubleshoot bugs, sometimes it gets confusing if someone uses
more comparison
, binding adapter etc.
g
type safety I think not really related to architecture
🎉 1
I wouldn’t recommend to use databindings only for type-safe access to views, ViewBinding indeed is a way to do that
databinding should be concidered if you build all your architecture on top of it
s
type safety I think not really related to architecture
Yup, I think that too.
g
XML and code mix into the same file
You do not mix code, you just bind some property to some view, I wouldn’t call it mixing code
troubleshoot bugs
It indeed may be a problem
s
XML and code mix into the same file XML
=> it looks like
Copy code
android:text= "${Converter.dateToString(viewmodel.birthDate)}"

android:textColor='@{ notice.action == "continue" ? @color/enabledPurple : @color/disabledGray}'
g
terrible databinding code
¯\_(ツ)_/¯
but it’s not a problem of databindings
it’s problem of code
Copy code
android:text="@{viewmodel.birthDate}"
Do not expose, data which you don’t want expose
Copy code
android:textColor='@color/purple_button_text'
android:enabled="@{notice.canContinue}
and
purple_button_text
just a simple android color with enable/default selector
But it wouldn’t be much better to mix ui logic with data binding logic if it would be done in some manually written binding
s
yup, I dont mean databinding is problem, I mean If we use databinding and implement some terrible bind like Google Support (https://developer.android.com/topic/libraries/data-binding/two-way) , it can make app is too much complex.
Thanks @gildor for your advice about these things.
g
But it’s just an example how to write two-way binding
👍 1
My only problems with databindings: build time, there is some hope with KSP, but not very high, it would be probably always quite significant Previously I would also mentio IDE support, but it improved a lot for last year, most of long waited requests actually fixed
j
@Sam I don't like data binding, purely because without strict developers it will be abused. The idea of putting any kind of java code into XML is in my opinion a bad idea and it has a big risk to become a big mess and any code you put in there can hardly be tested, only with instrumented (slow) tests that usually run unreliably. So if you choose databinding, I would advice to be strict and follow some made up rules: • Don't do what you first did 😄 Keep everything that is even slightly related to logic out from XML. • No if/else logic in xml files • Only bind pure data to a field. Mapping should be done beforehand, preferably in the view model, this is what @gildor showed.
➕ 2
mapping should in my opinion anyway be done in the view model. Model feeds data, View Model transforms the data into whatever the UI can directly display, UI directly displays it. In this way you only map in 1 location (the ViewModel) and keep the logic in 1 place
g
without strict developers it will be abused
a big risk to become a big mess
Same as any other approach
putting any kind of java code into XML is in my opinion a bad idea
It’s not “any java code”
I disagree that databinding is somehow worse than writing binding manually, abuse manual binding a lot easier, so if you write it in your view-related code it would have all the same problems as you mentioned: hard to test, only with UI tests, but at least databinding extremely limited in terms of code writing, but in your manually written view bind code you can do anything what you want, you need more discipline there
even very bad written binding is a lot easier to fix, just because it just a few lines of code in layout itself
g
If a binder(read data-binding library in case of Android) isn't used isn't MVVM similar to MVP (one difference here being presenter doesn't have access to its views)
j
Databinding is a tool to bind data to views, it is not part of mvvm, it is a tool to use and make your mvvm journey easier. You can still have mvvm, observe the livedata in your view (activity/fragment) and just set values to the views.
As long as the logic is in the viewmodel and the view itself just maps the observable data to view properties
Databinding is doing that for you
@gildor every architecture/solution should be used wisely, but databinding to me is very easy to use unwisely, more easy than other ways. Especially the problem that you cannot write unit tests for it is dangerous
But it is also my opinion. Not the truth :)
g
but databinding to me is very easy to use unwisely
Could you show an example?
Especially the problem that you cannot write unit tests for it is dangerous
You mentioned how manually written binding looks like, it's a fragment/activity with manual observing of data, how can you test it with unit tests? If you compare with databindings it actually better, less manually written code, less bugs. And as I mentioned previously, databinding also superior because it's much harder to mix you representation with your business logic, comparing to have everything in the fragment. bindings also often force you to extracting work with specific view apis to binding adapter, improving separation of concerns I don't want to say databindings is the best thing in the world, I worked on different architectures but bindings is definitely not the worst approach, they allow to have very clean code, remove boilerplate, have a nice border between layers, I see many problems too, but none of them is one of what is mentioned by you
j
Copy code
android:text= "${Converter.dateToString(viewmodel.birthDate)}"
android:textColor='@{ notice.action == "continue" ? @color/enabledPurple : @color/disabledGray}'
Like the example given by the original poster 🙂 Well if you use viewbinding, I am unsure as I do not, can't you mock it? I am unsure about it. In the old world with butterknife view mocking was super easy but I use kotlin synthetic things now (I know I shouldn't) and there I simply stopped writing tests. But anyway, I can imagine something like this:
Copy code
var viewBinding: MyViewBinding? = null

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    viewBinding = MyViewBinding.inflate(view) // Or whatever it is
    viewModel.viewState.observe(viewLifecycleOwner) { viewState ->
         viewBinding?.apply {
             error.apply {
                 isVisible = viewState.errorIsVisible
                 text = viewState.errorText
             }
             someText.text = viewState.someText
             someButton.isEnabled = viewState.someButtonIsEnabled
            // etc...
        }
    }
}
So in the case you can mock the ViewBinding, then if you would intercept the observer, you can trigger it and see if there is interaction with the views In this case you have here in Java/Kotlin the
setText(string)
instead of the
android:text="string"
so in terms of code it is almost the same. If you cannot mock the view layer, then this code is at least as testable as the databinding in xml 🙂
g
You can mock anything, question is should you do it or not? ViewBinding it's just a class with a bunch of getters for views, problem not to mock binding, problem starts if you want to mock views You really cannot test views without instrumentation tests or robolectric
j
Well you can mock a view class and check if it had invocations on it, after that you should trust the views themselves are already working and tested by Google
g
You can mock views, not sure that it a good idea, but anyway, you can do the same with data bindings
It's just generated code
Thought, I don't think it's good idea, same for databinding or manually written binding code
d
canonical mvvm is all about databinding. at least regarding microsoft's mvvm. if you don't use databinding then what is the point in such pattern? what is the difference from mvp?