I'm working with Xamarin and we are following the MVVM design pattern. For those who don't know what Xamarin is, it's a technology that allows us to build iOS and Android apps with shared code. Basically, your solution has 3 projects, one "Core" and then one per platform, the platform containing all the platform specific code, like UI animations, UI elements, or access to GPS and overall hardware/software specific to the device.
For the sake of the example, I'm gonna assume we're working on a Xamarin.iOS project, with one Core project having most of the logic.
My situation was the following, the project was written & released with too much code in the UIViewControllers of the iOS project, resulting in more work for the android developers. My job was to refactor those controllers and move code into the viewmodels because a lot of it was a mistake.
The problem is, the team architect thinks I pushed it too far. I'm gonna use actual examples.
Note that we use a lot of Action
objects to handle async calls. That's another debate.
Let's say we have data to load, Beneficiaries
, Accounts
, and Currencies
.
This requires 3 services in the ViewModel, and 6 Action
s. One xxxxServiceLoaded
and xxxxServiceFailed
for each of the data to load.
In the UI, the only thing that was done to the success or failure of each request was, pretty much, always the same thing. It was always loading a spinner, then calling another UI class that would handle data loading, but was abstracted and was always .loadData
for any data loaded.
To me, the ViewModel is pretty much your UI, it should know how it is assembled and how it reacts. And following that reasoning, I refactored the UIViewControllers from
OnCurrenciesFailed
OnCurrenciesSucceeded
OnBeneficiariesFailed
... (etc)
to
- DisplaySpinner
- HideSpinner
- DisplayError
- HideError
It reduced the amount of code in the controller, drastically. This applies to many controllers in the app. We're talking at least 10.000 lines of code.
This also removes all knowledge of the UI. It's been told the bare minimum and only UI. "Display this text". The only thing the UI does by itself is deciding how to animate and where to display said text, for example. I believe this is cleaner, cheaper and faster.
Also, it makes the work of android developers completely brain dead. You just subscribe to all actions and do what they tell you. "Display a spinner". Don't care why just do it. It's easier, far easier, than letting the controller know that there is a currency, that it's loading, and what to display when it failed or not. To me, this logic should be shared and not hidden in a controller.
But the architected refused my version, saying the ViewModel would be too tightly coupled to the view, making it not interchangeable if needed in the future, and that was more of a MVVMP (Presenter) design pattern, which is not what we are doing.
I kind of agree that it would be more coupled, but I've never seen anyone interchanging ViewModel or views, and the "risk" of that happening anytime soon. Developing android, on the other hand, is happening and will require more work and more browsing through ios code to understand requirements (which is a mistake !).
This raises questions:
- Am I using the pattern correctly by moving everything down in the ViewModel?
- Is MVVM the right pattern anyway? Since either way, it's either too coupled or has not enough shared code, is really MVVM the right choice? It seems to be hype, but the situation we're in shows a real flaw.