Which UI Pattern should you use?
A common question that mobile developers ask online is “Which UI pattern should I use” or “Which architecture should I learn to get a job?” or “What are the rules for viewmodels and when should I use them?”.
Discussing patterns is a favorite pastime of mobile engineers. But I try to stay away from leaning toward a specific one. Personally, I recommend using the simplest pattern possible. You can deliver a giant mobile app using only simple VM, MVC, or MVVM patterns.
However, what I learned is: The UI pattern is not as important as people might think.
Yes, need to pick a pattern to build our features. Even by not picking a pattern, you’re still using an approach to connect UI to the models. So you play the game too, even when you’re not playing.
And yes, patterns are great alignment tools within a team. It allows us to streamline our way of working, without having to answer the old question “How do I connect my UI to my models”. We can just pick a pattern, agree on it as a team, and move forward.
But, I want to ask you: Does it even matter which pattern you pick?
They all solve similar problems: which is to connect data to UI. They all have their pros and cons. Some use reactive techniques, others use simple closures, others create more modularity using routers, and so on.
Some require 3 letters, such as MVC, some require 6. However, “more letters” doesn’t always infer “more quality”.
Instead, let’s change the question.
UI migrations are inevitable
If you think about it, we keep ourselves busy with UI migrations. Not only to support the latest OS versions, but because we move from pattern to pattern.
Sometimes it’s because new patterns and architectures are trending, or because we want to learn new techniques. Sometimes it’s because it’s in job descriptions. In other cases, we love trying out new frameworks. And yet, sometimes it’s imposed upon us; Maybe a tech lead tells us to use a specific pattern, or it’s already enforced in a company that you join. Sometimes even Apple or Google promotes us to try out new things, such as changing from UIKit to SwiftUI or XML to Jetpack Compose!
It appears that, as mobile devs, change is inevitable when it comes to UI patterns.
Portable features
Instead, what I recommend is to focus on making your app more “UI-migration-proof” by making features more portable. In simple terms: Move more code to the model layer. Keep your UI layer thin.
Once you are aware that you have a “fat” UI layer, you realize that it’s harder to change to a new pattern, architecture, or UI paradigm.
Instead, if your features work well, even without UI (where possible), then it’s easier to support multiple UI patterns, paradigms, and so on. You can more easily support multiple targets — such as delivering a VR app, watch app, module, or headless client.
Without a strong dependency on UI, it’s easier to unit-test more of your features, and it’s easier to disconnect features from screens, so that they can run in the background, regardless of the current navigation-tree.
Learn more
There are various ways to deliver more portable features, and I am sharing some ideas in chapter 9 of the Mobile System Design book. The new upcoming chapter “Portable features” will cover this in-depth with a more hands-on approach, which will release very soon.
Until then, I recommend checking out my latest video below.
To read more on my thoughts on this, check out the article ‘Uh oh, you picked the wrong UI architecture’.
So instead of asking yourself “Which pattern should I use?”, ask yourself, “How can I make my feature more portable?”
Then everything will fall into place naturally.