Mediator Design pattern -swift- Examples
The Mediator Design Pattern is a behavioral design pattern that promotes loose coupling between a set of objects by encapsulating how they interact and communicate with each other through a central mediator object.
It allows for the reduction of dependencies between objects by replacing direct object-to-object interactions with indirect interactions through the mediator.
The mediator design pattern is a behavioral pattern that facilitates communication between different objects or components of a system by using a mediator object to coordinate their interactions.
Here are some benefits of using the mediator design pattern:
Decoupling of components: The mediator pattern helps to reduce the coupling between components in a system, making them more independent and easier to modify or maintain. Each component only needs to know about the mediator and not the other components in the system.
Centralized control: The mediator acts as a central control point for communication between components. This makes it easier to manage and modify the communication behavior of the system.
Improved scalability: As the number of components in a system increases, the mediator pattern can help to manage the interactions between them, making the system more scalable.
Easier testing: The mediator pattern makes it easier to test individual components in isolation, as the mediator can be replaced with a test double or mock object.
Encapsulation: The mediator pattern encapsulates the communication behavior of the system in a single object, making it easier to understand and modify.
Reusability: The mediator object can be reused in different contexts and scenarios, making the system more modular and flexible.
Here are different examples to learn Mediator Design Patterns:-
class User {
let name: String
var chatRoom: ChatRoom
init(name: String, chatRoom: ChatRoom) {
self.name = name
self.chatRoom = chatRoom
}
func sendMessage(message: String) {
chatRoom.sendMessage(message: message, sender: self)
}
func receiveMessage(message: String) {
print("\(name) received message: \(message)")
}
}
class ChatRoom {
var users: [User] = []
func addUser(user: User) {
users.append(user)
}
func sendMessage(message: String, sender: User) {
for user in users {
if user != sender {
user.receiveMessage(message: message)
}
}
}
}
let chatRoom = ChatRoom()
let user1 = User(name: "Alice", chatRoom: chatRoom)
let user2 = User(name: "Bob", chatRoom: chatRoom)
let user3 = User(name: "Charlie", chatRoom: chatRoom)
chatRoom.addUser(user: user1)
chatRoom.addUser(user: user2)
chatRoom.addUser(user: user3)
user1.sendMessage(message: "Hi, everyone!")
user2.sendMessage(message: "Hey, Alice and Charlie!")
user3.sendMessage(message: "What's up, guys?")
class User {
let id: Int
let name: String
let email: String
init(id: Int, name: String, email: String) {
self.id = id
self.name = name
self.email = email
}
}
class APIService {
var users: [User] = []
func fetchUser(id: Int) -> User? {
return users.first(where: { $0.id == id })
}
func addUser(user: User) {
users.append(user)
}
}
class APIMediator {
let apiService: APIService
init(apiService: APIService) {
self.apiService = apiService
}
func fetchUser(id: Int) -> User? {
return apiService.fetchUser(id: id)
}
func addUser(user: User) {
apiService.addUser(user: user)
}
}
let apiService = APIService()
let apiMediator = APIMediator(apiService: apiService)
let user1 = User(id: 1, name: "Alice", email: "alice@example.com")
let user2 = User(id: 2, name: "Bob", email: "bob@example.com")
apiMediator.addUser(user: user1)
apiMediator.addUser(user: user2)
if let fetchedUser = apiMediator.fetchUser(id: 1) {
print("Fetched user: \(fetchedUser.name), \(fetchedUser.email)")
}
In this example, the client communicates with the APIMediator to fetch
and add users, without needing to know the implementation details
of the APIService. This allows for better decoupling between the client
and the API service, and makes it easier to modify or replace the API
service in the future without affecting the client code.
class Buyer {
let id: Int
let name: String
var shoppingCart: [Product] = []
init(id: Int, name: String) {
self.id = id
self.name = name
}
func addToCart(product: Product) {
shoppingCart.append(product)
}
func checkout() {
// send checkout request to mediator
}
}
class Seller {
let id: Int
let name: String
var products: [Product] = []
init(id: Int, name: String) {
self.id = id
self.name = name
}
func addProduct(product: Product) {
products.append(product)
}
func removeProduct(product: Product) {
if let index = products.firstIndex(of: product) {
products.remove(at: index)
}
}
}
class Marketplace {
var sellers: [Seller] = []
var buyers: [Buyer] = []
func addSeller(seller: Seller) {
sellers.append(seller)
}
func addBuyer(buyer: Buyer) {
buyers.append(buyer)
}
}
class MarketplaceMediator {
var sellers: [Seller] = []
var buyers: [Buyer] = []
func addSeller(seller: Seller) {
sellers.append(seller)
}
func addBuyer(buyer: Buyer) {
buyers.append(buyer)
}
func fetchProduct(sellerId: Int, productId: Int) -> Product? {
if let seller = sellers.first(where: { $0.id == sellerId }) {
return seller.products.first(where: { $0.id == productId })
}
return nil
}
func checkout(buyerId: Int) {
if let buyer = buyers.first(where: { $0.id == buyerId }) {
// process checkout and notify seller(s)
}
}
func addProduct(sellerId: Int, product: Product) {
if let seller = sellers.first(where: { $0.id == sellerId }) {
seller.addProduct(product: product)
}
}
func removeProduct(sellerId: Int, product: Product) {
if let seller = sellers.first(where: { $0.id == sellerId }) {
seller.removeProduct(product: product)
}
}
}
// Protocol for the marketplace mediator
protocol MarketplaceMediator {
func addBuyer(buyer: Buyer)
func addSeller(seller: Seller)
func notifySeller(item: Item)
func notifyBuyer(item: Item)
}
// Buyer class
class Buyer {
let name: String
var mediator: MarketplaceMediator?
init(name: String) {
self.name = name
}
func notify(item: Item) {
print("\(name) received notification about \(item.name) from the marketplace.")
}
func buy(item: Item) {
print("\(name) is buying \(item.name) from the marketplace.")
}
}
// Seller class
class Seller {
let name: String
var mediator: MarketplaceMediator?
init(name: String) {
self.name = name
}
func notify(item: Item) {
print("\(name) received notification about \(item.name) from the marketplace.")
}
func sell(item: Item) {
print("\(name) is selling \(item.name) on the marketplace.")
mediator?.notifyBuyer(item: item)
}
}
// Item class
class Item {
let name: String
init(name: String) {
self.name = name
}
}
// Marketplace class
class Marketplace: MarketplaceMediator {
var buyers: [Buyer] = []
var sellers: [Seller] = []
func addBuyer(buyer: Buyer) {
buyers.append(buyer)
buyer.mediator = self
}
func addSeller(seller: Seller) {
sellers.append(seller)
seller.mediator = self
}
func notifySeller(item: Item) {
for seller in sellers {
seller.notify(item: item)
}
}
func notifyBuyer(item: Item) {
for buyer in buyers {
buyer.notify(item: item)
}
}
}
// Usage
let marketplace = Marketplace()
let alice = Buyer(name: "Alice")
let bob = Buyer(name: "Bob")
marketplace.addBuyer(buyer: alice)
marketplace.addBuyer(buyer: bob)
let charlie = Seller(name: "Charlie")
let dave = Seller(name: "Dave")
marketplace.addSeller(seller: charlie)
marketplace.addSeller(seller: dave)
let item1 = Item(name: "Item 1")
charlie.sell(item: item1)
alice.buy(item: item1)