6

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 Actions. 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.
  • 1
    Your Team Architect is the principal arbiter here, not us. You should listen to him. Ask him to explain his decisions, and then have an open mind so that you can understand his rationales. – Robert Harvey Mar 27 '17 at 15:45
  • 1
    My two cents: the controller should really do very little, and understand even less about what's going on. In most MV* architectures, the controller does little more than serve as a switchyard; nearly all of the logic that matters belongs somewhere else. And I don't buy your argument about spinners; the whole point of decoupling is that the details you describe are deferred to the places in the architecture where they belong. So yes; it's just a spinner, and something else should care about the details. – Robert Harvey Mar 27 '17 at 15:49
  • That's what we did, and I know follow the guidelines. This question is purely for my own culture, not to shove up to his face and say 'I told you so'. What I see is, not matter what we do there seems to be a downside. Which leads to believe either we do something wrong or there is a different pattern to follow. And that he agreed to it himself – Gil Sand Mar 27 '17 at 15:50
  • 1
    What is the responsibility of 'UIViewControllers' in MVVM pattern? – Fabio Mar 27 '17 at 16:27
  • 2
    If your solution produces less code, and the only argument the architect can come up with is "too tightly coupled", and you can prove that the coupling is needed, then the architect is wrong. However, you may have an over-engineering type of architect, in which case, you just have to watch the code explode in size. Also "the right pattern" is not the best question, but rather, what produces the simplest, smallest solution. – Frank Hileman Mar 30 '17 at 0:33
1

MVVM is a great design pattern. I haven't worked with Xamarin but i work with Kendo MVVM, Angular, and MVC. The design pattern to keep in mind is "Skinny controllers, fat models". You want your business logic agnostic to the viewmodel and to the persistence layer. Coupling is worse than repeating yourself because if you want to make a change you can break so much. There are always exceptions to the rules (i.e. small projects), but for big projects with many develops you will find nice clean layers will help maintainability in the long run.

1

I haven't used Xamarin, but for MVVM to work well, you need to use binding--which is something that is inherent with XAML based APIs. I have doubts that you are really using MVVM since there really isn't a Controller in that pattern.

The way it works in standard WPF or UAP apps is:

  • Your Model represents the business logic
  • Your ViewModel has a property named Model and additional properties that are used to interact with the view. This is where your page/control logic lives.
  • Your View binds to the ViewModel directly

There isn't a need for a controller in this scenario. There are some further tricks of the trade.

  • Use a RelayCommand (example) implementation of ICommand. This binds the actions of an ICommand to methods on your ViewModel. It also lets you control whether buttons are active or not.
  • Use a Locator to resolve the ViewModel to View mapping.

Those aren't core to MVVM, but they help.

If your Views are essentially the same across platforms, then the ViewModel having your page logic is no problem. Particularly if you can design the ViewModel to not need any references to the View controls themselves.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.