Delegate Pattern in Simple Terms
Discover how the delegate pattern enables one object to offload tasks to another, illustrated through a real-world restaurant analogy and a Swift code example featuring a waiter and chef collaboration.
TL;DR #
Object A outsources a specific job to Object B, without knowing the details of how it’s done.
Real-Life Example #
Imagine you’re ordering food in a restaurant:
- Waiter (B): Takes your order.
- Chef (A): Actually cooks the food.
The waiter delegates the task of preparing the food to the chef. Similarly, in code, one class can delegate specific responsibilities to another.
Code example #
// Define a protocol that outlines the responsibilities the Chef must handle
protocol KitchenDelegate {
func prepareFood(order: String) -> String
}
// Chef class (A) - The one who performs the delegated task
class Chef: KitchenDelegate {
func prepareFood(order: String) -> String {
return "Chef has prepared your \(order). Enjoy your meal!"
}
}
// Waiter class (B) - The one who delegates the task
class Waiter {
var delegate: KitchenDelegate? // The delegate property, optional since it might not always be set
func takeOrder(order: String) {
print("Waiter: I've taken your order for \(order).")
// Delegate the food preparation to the Chef if available
if let preparedFood = delegate?.prepareFood(order: order) {
print("Waiter: Here’s your food. \(preparedFood)")
} else {
print("Waiter: Sorry, no chef available to prepare your \(order).")
}
}
}
// Example usage
func restaurantScenario() {
// Create instances
let chef = Chef()
let waiter = Waiter()
// Set the chef as the waiter's delegate
waiter.delegate = chef
// Customer places an order
waiter.takeOrder(order: "Spaghetti Carbonara")
// Now try without a chef
let loneWaiter = Waiter() // No delegate assigned
loneWaiter.takeOrder(order: "Pizza Margherita")
}
// Run the scenario
restaurantScenario()