“This design pattern is implemented by defining a protocol that encapsulates the delegated responsibilities, such that a conforming type(known as a delegate) is guaranteed to provide the functionality that has been delegated.” ; Swift Language Guide - Protocols
// This protocol will hold everything the manager class needs their assistant to do
protocol ManagerDelegate: AnyObject {
func doLaundry(for manager: Manager, laundry: [Clothes]) -> [Clothes]
func howMuchMoneyDidWeMake() -> Int
func whatBearIsBest() -> String
}
class Manager {
// the manager doesn't care what class their assistant is,
// only that they can do what the manager needs them to do
weak var assistant: ManagerDelegate?
// Whever the manager needs those tasks done, they just have the assistant do it
func performEndOfDayTasks() {
if today.isMonday {
cleanClothes = assistant.doLaudry(for: self, laundry: dirtyClothes)
} else if today.isFriday {
let profit = assistant.howMuchMoneyDidWeMake()
tellBoss("We made \\(profit) dollars this week boss!")
}
}
}
// The assistant adopts the protocol and this code will not compile
// unless they meet all the requirements of the protocol
class Assistant: ManagerDelegate {
func doLaundry(for manager: Manager, laundry: [Clothes]) -> [Clothes] {
var cleanClothes = washClothes(laundry)
dryClothes(cleanClothes)
foldClothes(cleanClothes)
return cleanClothes
}
func howMuchMoneyDidWeMake() -> Int {
return ledger.profit
}
func whatBearIsBest() -> String {
return "There are basically two schools of thought..."
}
}