iOS Development: Is there actually an MVC crisis?
I’m fairly sure I am going to get flamed regarding the opinions voiced below, but I feel compelled to publish them nonetheless.
Does the Massive View Controller problem actually exist?
This is an interesting question. I primarily develop for iOS in my professional capacity, and for macOS in my private capacity, consequently, I read a large number of articles and blogs relating to Swift and Objective C development. A number of these blogs advocate the use of the MVVM ( Model-View-View Model ) pattern to counter the supposed Massive View Controller problem that they claim results when one makes use of the MVC (Model-View -Controller) pattern. Many (in my opinion — uninformed) iOS developers seem to think there is an intrinsic problem with the use of MVC specifically in iOS applications as well as in general. I vehemently dispute this premise.
We all know there is no such thing as a silver bullet since solutions should be tailored to problems. These developers cite what they call the Massive View Controller problem, saying that applications developed using MVC results in View Controllers that are excessively large and excessively complex. I have architected, designed and coded some large and complex iOS and macOS applications and I have never experienced this problem. Yes, the size of a View Controller (measured in lines of code) does correlate with the complexity of the solution, but that is true irrespective of the patterns used.
I contend that inexperienced developers, developers who are insufficiently steeped in the iOS frameworks and developers who have an incomplete grasp of OO (Object Orientation) are the ones who cause, experience and lament the Massive View Controller problem. They seem to be unmotivated to learn how to use MVC and OO properly. Consequently, they prefer to use MVVM because they probably learnt of that pattern elsewhere or learnt it before MVC. People hate change (although I suppose you could say that about me given the argument I am presenting). I am not saying that MVC is the panacea for Apple platform development ills, but I do think it has been unfairly maligned, and MVVM is not the elixir it’s made out to be.
Smalltalk defined MVC first
I first learnt of MVC while developing Smalltalk applications on OS/2 using both Smalltalk/VPM and VisualWorks. Of course, the way MVC was implemented in Smalltalk is significantly different from the way Apple describes MVC (for a complete discussion surrounding this, see Martin Fowler’s excellent article). Nonetheless, I started using MVC, albeit slightly differently in Smalltalk. I never experienced any problems there.
NeXT Adopted MVC but bastardised it
I have always been an Apple fan. I’m a long-term Mac developer who, having not used Windows in over 25 years, is not one of the recent converts who carry on as if they invented the Mac, even though they have only recently learned of its benefits, and who as little as seven years ago were telling me that Apple was dead. I have been developing in Objective C since NeXT days, and so first used Objective C and MVC very effectively on that wonderful platform. When Mac OS X was first released, I was overjoyed to see Objective C on Mac OS X and set to coding Mac OS X applications using Objective C and MVC rather than CodeWarrior, C++ and Event Driven loops. Again MVC worked just fine for me there.
When the iPhone appeared, and the SDK was first made available, I jumped in there too. Once again MVC worked just fine for me on iOS. Unlike many younger developers, I read the Apple documentation, carefully, repeatedly. I find the information there incredibly useful (despite the paucity of it), and often when I am reading about a particular subject, I subliminally note helpful things — not directly related to the subject at hand — that come to mind when problems directly related to them become relevant.
I know and use things such as Key Value Coding, Key Value Observing, Key Paths, Cocoa Bindings, Formatters, Value Converters, Dependency Management for Models and Dependency Injection on a regular basis. I find ignorance regarding these classes rife, particularly amongst novices (who use Stack Overflow to solve everything rather than reading documentation) and developers who have migrated to iOS or macOS from other platforms because somehow despite their dire predictions, iOS just won’t go away. These developers do not use the aforementioned classes defined in AppKit, UIKit and Foundation, and end up writing View Controllers that ARE massive, ARE complex, and consequently ARE brittle.
They write bad code that mixes business logic, database logic, network logic and presentation logic directly into their View Controllers. Why, regarding basic OO, would one ever do that sort of thing rather than encapsulating those pieces of logic in support classes that export a simplified API, then making use of those support classes in their View Controllers?
Object Orientation Should Rule
The fundamental tenets of OO are Polymorphism, Encapsulation and Inheritance, and the greatest of these is Encapsulation in my opinion. The SOLID principles define the Single Responsibility Principle (as does Apple I might add) which means that objects should do one small single thing well, and these abstractions should be combined into other abstractions that do a single more complex thing and so on up the line.
Turtles all the way down so to speak. Best practice also suggests favouring composition over inheritance which implies View Controllers should make limited use of inherited functionality from superclass controllers rather using logic imported by means of composition. Excessively complex View Controllers often result when developers use superclass controllers to add logic that may be common across a number of View Controllers, rather than accessing that logic via support objects.
Following my suggested approach results in View Controllers that support complex, sophisticated logic without being excessively large or excessively complex themselves because they export large amounts of complexity to specialist objects that encapsulate said complexity in simple, clean APIs. Using Bindings (or similar abstractions) either custom developed for iOS (because Apple has not ported Cocoa Bindings to iOS, Apple alone knows why not) using Key Value Coding, Key Paths, Key Value Observing or Value Models (which are explained later) or directly using AppKit’s Cocoa Bindings significantly reduces code complexity and code size in View Controllers. A large number developers of whom I am aware claim to be skilled macOS developers but have never heard of Cocoa Bindings, while many iOS developers I have interacted with seem terrified of using existing protocols (such as Key Paths and Key Value Observing ) in UIKit and Foundation to build their own Binding implementations.
Bindings — Why, When and Where
Bindings are not new-fangled technology, VisualWorks Smalltalk defined something called Value Models (see this article by Bobby Wolf on the subject of Value Models) with similar properties over 25 years ago. These abstractions allow sophisticated management of variable dependency, dependency injection, automated change propagation and with a little bit of hacking, clever, simple and easy to use integration with iOS controls. But these days old is viewed as bad. I have repeatedly over the years implemented ValueModels in Objective C (which is easy), and Swift (less easy) and very successfully used them to combat complexity in View Controllers. Reactive programming claims to have invented these concepts. It did not. They were invented by Alan Kay et al. for VisualWorks Smalltalk over two decades ago, nonetheless Reactive programming is another valid solution. I have released a small implementation of ValueModels on GitHub (see here) for iOS in Objective C which demonstrates how to implement a few ValueModels. When one combines these abstractions, writing small, efficient and yet sophisticated View Controllers using MVC becomes almost trivial.
MVVM is a Good Pattern, but so are MVC, EBI and VIPER
I am not saying that MVVM does not have its uses, it does, and it’s always good practice to separate presentation logic from other logic since that is fundamentally sound architecture. Using Key Paths, however, allows one to do this almost trivially without the use of a View Model and without tightly coupling View Controllers, Models or iOS Controls. I am also of the opinion that using the EBI (Entity Boundary Interactor) pattern coupled with MVC is a superior solution to MVVM if used with the aforementioned supporting protocols and classes. Even the inventors of the MVVM pattern suggest that it may not always be the best approach.
I have seen a number of implementations of MVVM where the View Models suffer from the Massive View Model problem. I have seen cases where developers use View Models to do localisation rather than using the underlying support provided by iOS. I have seen developers embed business logic in View Models. I have seen developers creating hideous “Util” classes that provide shared Table View Cell and iOS Control presentation logic rather than just passing models (in the form of untyped objects implementing specific protocols) into Table View Cells, coupled with Formatters or Value Converters, and allowing the Table View Cell or iOS Control subclass to define its own presentation logic in a loosely coupled and reusable way with Key Paths and Key Value Observing.
As a result of this, presentation logic from the Table View Cell subclass or iOS Control leaks into either the View Controller (thus contributing to the complexity and size of View Controllers) or gets exported to these abominable “Util” classes which in turn become tightly coupled to the Table View Cells or iOS Controls. In my opinion, MVVM can result in as much complexity and size as MVC or EBI.
Bad Work Persons Always Blame Their Tools
Unskilled uninformed developers will always produce poor implementations whether they use MVVM or MVC or EBI. Skilled informed developers will produce elegant, slim and small View Controllers whether they use MVC or whether they use MVVM. A bad work person always blames their tools thus unskilled developers blame MVC, not because it’s flawed but because they are.
I’m not the only iOS developer who has this view. There is an ever-increasing number of us who feel the same way; you might even think of us as counter reformationists.
This article was first published on Medium.com: https://medium.com/@vincecoetzee/is-there-actually-an-mvc-crisis-2ce94b3aa011