This week’s issue of This Week In Swift included a link to this discussion of iOS architecture patterns including MVC, MVP, MVVM, and VIPER, with this as part of the description:
I've heard about VIPER, but haven't used it yet. I really like the idea of having a Router object. But obviously, having a super complex architecture like that right away is over-architecting.
I have a problem with the characterization of VIPER, right out of the gate, as across-the-board “obviously super complex”, for a few reasons.
Now, let me preface this post by saying: yes, I am about to write six hundred words in response to what was certainly an off-the-cuff comment. But I think this provides a nice opportunity for some Simple vs. Easy discussion and some consideration about how we evaluate software architecture choices.
I’ll also note that you should absolutely go subscribe to This Week In Swift. It’s very useful.
Is that really obvious? Let’s consider some factors one should take into account when making architectural decisions.
What are your requirements? How many of your requirements are actually known right now? How large is this app going to be? How many people are on your team? What are their experience levels and areas of expertise? Are you planning to revisit decisions like this down the road once your app and its requirements fleshed out, or are you committed to shipping pretty much exactly what you start out writing? Can you effectively prioritize medium-to-large restructuring projects at your organization to relieve problematic areas of technical debt?
Each of these questions should clearly influence your architectural decisions early in the project, and this decision is absolutely not “obvious”. There are combinations of answers to these questions which strongly point to MVC, MVVM, or VIPER as a good choice at the outset of a project.
For context before reading this section, I recommend watching Rich Hickey’s Simple Made Easy talk. I’m going to use his distinction between simplicity and ease of use in this discussion.
I do not think MVVM or VIPER are inherently “super complex”. In fact I think those are—generally speaking—both simpler, better designs than MVC. But I do agree that VIPER is less easy to get started with.
MVC is easy to get started with: you have clear definitions for models and views, and everything else goes into “controllers”. Easy! On iOS, those ill-defined controllers tend to be your view controllers, leading to a classic “Massive View Controller” scenario. This is definitely easy—you know where things go and can start hacking something together right away—but as your app grows its architecture becomes more and more complex, and MVC doesn’t help you manage it.
MVC is easy, but not simple.
MVVM is a little harder to get started with, but as you build your app, the clearer division of responsibility out of view controllers becomes more clearly useful.
This improved division of responsibilities makes MVVM a little harder to get started with than MVC, but also simpler.
I haven’t actually written a full app with VIPER, but I would think seriously about it if the answers to the questions I outlined above called for it. VIPER calls out and forces you to think about and divide out more responsibilities up front, so I guess it’s not really easy to get started with. But is strict division of responsibility really “obviously super complex”??
Clear divisions of responsibility make VIPER reasonably simple and flexible for large apps, but starting out with it will not be as easy as with MVC. That doesn’t necessarily make it a wrong choice.
If you know you’re building a large app, you have a reasonably experienced team, and you won’t likely have a chance to significantly rework your architecture down the road, is VIPER still obviously a wrong choice from the outset?
As always, I welcome discussion and feedback; I’m @cdzombak on Twitter.