Soroush Khanlou recently wrote MVVM is Not Very Good in which he describes MVVM as an anti-pattern. Soroush explains why MVVM adds confusion and doesn’t actually address the problem it claims to solve. I fully agree. I’d like to add a little bit of background on MVVM and why it’s inherently a poor fit for iOS apps.
MVVM has its’ roots in the Windows Presentation Foundation (WPF). MVVM is an evolution of the Presentation Model as described by Martin Fowler in Patterns of Enterprise Application Architecture . The technologies in WPF and the type of apps it was designed to facilitate are considerably different from iOS apps. WPF apps are desktop apps which include enterprise apps. In an enterprise app the Model can be a huge monolith that would serve the needs of an entire enterprise. Each new enterprise app would re-use this same monolithic Model. In this context the ViewModel is intended to tame the Model into something more manageable. For example, if we were making an app for the sales department then we’d create a ViewModel that provided accesses to the sales report services but it would not include the QA services or the customer support services. In iOS we don’t have the Monolithic Model problem because we generally build the model from scratch with each new app.
The fundamental design of WPF differs from UIKit in 2 significant ways. WPF was designed so that code was placed in a Form subclass which is a kin to a UIWindow. This meant that business logic (which should belong in the Model) was being placed in the View. ViewModels are a solution to this problem. The design of UIKit does not encourage Model logic being placed in the View. UIKit views are already skinny so a ViewModel, as designed for WPF, is not required in iOS. The other difference between WPF and UIKit is that WPF supports bindings. Bindings make a great deal of the code that is traditionally put in the Controller obsolete. iOS doesn’t have bindings so requires an object that can take data from the Model and pass it onto the View – and that’s exactly what UIViewController is designed to do.
In iOS apps we do not have the monolithic Model problem or the Fat View problem and we also do not have bindings. This suggests that MVVM is fundamentally a poor architecture for iOS. In fact, the differences between WPF and UIKit mean that ‘iOS MVVM’ will be so fundamentally different from ‘WPF MVVM’ that using ‘MVVM’ to describe both architectures is misleading.
So how did ‘iOS MVVM’ come to be? I believe the root problem is not that MVC is flawed but that there is a misunderstanding of the role of the Model in Cocoa MVC. The Model should be rich. My rule of thumb is “if I were to port this iOS app to OS X would I still need this functionality?” If the answer is “yes” then it most likely belongs in the Model.
It seems many devs still see the Model as being a dumb data store (I’ve occasionally heard the term “models” which I find telling). Yes, one of the roles of the Model is to persist data, but a rich Model will also contain objects with a diverse range of roles. Networking is a good example. Networking code is often erroneously put in the Controller when it should be in the Model ( Apple’s docs even mention that networking code belongs in the Model: “When a model object changes (for example, new data is received over a network connection), it notifies a controller object, which updates the appropriate view objects”).
If you’re interested in reading more about MVC, and MVVM then I suggest:
- Martin Fowlers website and in particular Development of Further Patterns of Enterprise Application Architecture
- Graham Lee’s series on MVC .