We talked about design systems in UX/UI design, and this time on our Thursdays Learn@Lunch, our Head of Mobile, Kristijan Delivuk, spoke about design patterns and architecture in mobile development. He focused on architecture for iOS, but you can apply the same to other frameworks.
During our weekly (online) Thursdays Learn@Lunch, someone on the team presents a new technology, a solution they made for a client or something interesting from their field. It’s where we can not only learn something new but also understand a part of the work other team members are doing or learn a solution we can apply to our project.
What are Design Patterns?
So, Kristijan began his Learn@Lunch with a simple definition of design patterns:
Design patterns are reusable solutions to common problems in software design.
He highlighted that they aren’t concrete implementations but rather serve as starting points for writing code. They describe generic solutions to problems that developers have encountered many times before.
In a nutshell, design patterns are great for:
- Creating a common language between developers
- Fast-tracking developer onboarding
- Making the development process faster and simpler
- To not have to always think of something new, but outwit the challenge with an already existing solution
- Also, knowing design and architectural patterns allows a developer to spot similarities between codes
Types of Design Patterns in Mobile Development
Our Head of Mobile development continued talking about three types of design patterns:
- Creational – describe how to create or instantiate objects, and the most used ones are Builder and Singleton
- Structural – describe how objects are composed and combined to form larger structures (Model-View-Controller, Model-View-ViewModel, Decorator, Adapter, Facade)
- Behavioral – describe how objects communicate with each other (Delegation, Strategy, and Observer)
You may have heard about Model-View-Controller and Model-View-ViewModel being sometimes called architectural patterns. But, they are actually design patterns that describe how the architecture of some applications is made. They are broader in scope than design patterns, which only span components or pieces of an app. Architectural patterns can even use or encompass several design patterns, and Kristijan talked later about them.
You may be wondering if knowing a type of design pattern really matters. Well, yes…and no. It’s not helpful to memorize all patterns by type. Most developers don’t do this.
However, if you’re unsure whether a particular pattern will work, it’s sometimes useful to consider others of the same type. You might find one that works better for your specific problem.
Just like there are benefits to design patterns, there are also downsides. Kristijan mentioned three:
- If you overuse design patterns, your project can become overly complex
- Many design patterns are redundant because of the modern programming languages
- Design patterns are a lazy substitute for learning object-oriented principles
The Singleton Pattern
The Singleton Pattern is one of the most used creational design patterns. It ensures that only one instance exists for a given class and that there’s global access to that point of instance. Having one global instance which has access to all others and uses all others is not really something that should be used.
But, for example, Apple uses this approach in its ecosystem. Communication with the hardware part and of the smartphone goes through shared instances like:
- UserDefaults.standard gives access to temporary memory,
- UIApplication.shared provides access to other smartphone entries,
- UIScreen.main for screen access,
- FileManager.default gives file access.
Overall, the Singleton pattern is okay, but the downside is that the aforementioned global instance sees and uses everything, making testing a considerable problem. So Kristijan suggests that if you encounter a situation where you’re want to use a singleton, you should first consider other ways to accomplish your task.
The Observer Pattern
The Observer pattern you can use whenever you want to listen to changes made on another object. It consists of three objects:
- Observer, which receives updates
- Subscriber, which sends updates
- And the value, which is the underlying object that’s changed
It’s mainly used when we want to receive changes on the object or a part of the system, and it’s helpful when the whole functionality paradigm is based on the observer pattern.
The Decorator Pattern
Then we have the Decorator Design pattern, which dynamically adds behaviors and responsibilities to an object without modifying its code, like extensions and delegations.
Kristijan defined extensions as adding functionality to a class without overriding it. We can easily add it without changing the primary structure and add a new property without modifying the existing class.
The Delegation Pattern
When we talk about delegation patterns, we talk about mechanisms in which one object acts on behalf of or in coordination with another object. That object permits the second one to act as it or do some other action.
So we have two different objects:
- The delegate
- The object that needs the delegate
Apple uses this approach in most of the UIKit classes:
UITableView, UITextView, UITextField, UIWebView, UICollectionView, UIPickerView, UIGestureRecognizer, UIScrollView
Apart from these design patterns in Mobile Development and since they started having issues on interactions between client and the server, iOS moved to better patterns. Read more on MVP, MVVM, MVC, and VIPER in the next blog, Architecture in Mobile Development.