Greetings, traveler!
We continue to discuss Design Patterns. It is the turn of another Behavioral Design Pattern, the Mediator. The Mediator is a design pattern that helps reduce chaotic dependencies between objects by restricting direct connections and forcing objects to interact through an intermediary. This pattern helps create a more organized and predictable system and provides a way of object decoupling.
Example of usage
So, straight to the point? Let’s look at the example of updating the operating system version of your iPhone. You have an iPhone, right?
The software development team needs to release an iOS update to do this. The marketing team should then describe the new features clearly and engagingly and notify users about the update. We, as users, will promptly download and install the update.
Now, let’s put this whole story into code.
So, we have a development team and three other members who interact with it when an operating system update is released. Let’s start with the operating system.
struct iOS {
var version: Double
}
Now, we will create protocols for the user and the marketing department — the mediator.
protocol UserProtocol {
func handleNotification(about: iOS)
}
protocol MediatorProtocol {
func notify(about os: iOS)
}
And now, let’s take a look at the implementation of these protocols.
final class User: UserProtocol {
func handleNotification(about os: iOS) {
print("Update iOS version to \(os.version)")
}
}
final class MarketingDepartment: MediatorProtocol {
private let users: [UserProtocol]
init(users: [UserProtocol]) {
self.users = users
}
func notify(about os: iOS) {
users.forEach {
$0.handleNotification(about: os)
}
}
}
So, who will make the update itself? Of course, this is our favorite Apple Software Department.
final class SoftwareDepartment {
private let mediator: MediatorProtocol
init(mediator: MediatorProtocol) {
self.mediator = mediator
}
func update(os: iOS) {
mediator.notify(about: os)
}
}
Now we can use it all together.
let users = [User(), User(), User()]
let marketing = MarketingDepartment(users: users)
let development = SoftwareDepartment(mediator: marketing)
let os = iOS(version: 18.0)
development.update(os: os)
Conclusion
This behavioral design pattern allowed us to avoid direct interaction between the software department and users. The marketing department has taken on this responsibility. As a result, we have avoided the difficulties associated with dependency injection, and the objects are not interconnected. That’s convenient! Now, let’s move on to the next design pattern, the Memento pattern.
Check out other posts in the Design Patterns series:
- Visitor Design Pattern in Swift
- Themplate Method Design Pattern in Swift
- Strategy Design Pattern in Swift
- State Design Pattern in Swift
- Observer Design Pattern in Swift
- Memento Design Pattern in Swift
- Iterator Design Pattern in Swift
- Command Design Pattern in Swift
- Chain of Responsibility Design Pattern in Swift
- Proxy Design Pattern in Swift
- FlyWeight Design Pattern in Swift
- Facade Design Pattern in Swift
- Decorator Design Pattern in Swift
- Composite Design Pattern in Swift
- Bridge Design Pattern in Swift
- Adapter Design Pattern in Swift
- Singleton Design Pattern in Swift
- Prototype Design Pattern in Swift
- Builder Design Pattern in Swift
- Abstract Factory Design Pattern in Swift
- Factory Method Design Pattern in Swift
- Design Patterns: Basics