在上一篇中,我們討論了如何使用 Delegate 和 Protocol 實現單人通訊的例子,當守衛發出「領包裹通知」時,需要事先指定好代理人,才能將通知傳送給正確的住戶。這次,我們將擴展這個概念,介紹如何處理更複雜的「群組通訊」情境。
想像一下,守衛不需要知道具體哪位住戶,而是只需告訴系統某一門牌號碼有包裹到達,系統便能自動通知所有登記在這個門牌號碼下的住戶。這將使應用程式的通訊更靈活且方便,適合多對多的通信場景。
在這個更複雜但實用的例子中,我們將探討如何設計「群組通訊」。當保全只告知某一門牌有包裹到達時,所有住在該門牌的住戶都會收到通知。這樣的設計不僅簡化了通訊過程,也使得代理模式更符合多住戶的場景。
Step 1: 更新 Protocol
首先,我們在 protocol 的 "領包裹通知" 方法中加入一個參數來表示門牌號碼,讓系統根據門牌號來發送通知:
protocol 智生活APP: AnyObject {
func 領包裹通知(forDoorNumber doorNumber: String)
}
Step 2: 守衛改用陣列存儲住戶
接著,我們將守衛的代理人從單個住戶改成一個陣列,這樣便可以同時通知多個住戶:
var 登記的住戶: [智生活APP] = []
func 登記住戶(resident: 智生活APP) {
登記的住戶.append(resident)
}
Step 3: 群發通知
當有包裹到達時,守衛會依據門牌號通知所有住戶,並且住戶會根據門牌號來判斷是否是他們的包裹:
func 領包裹通知(forDoorNumber doorNumber: String) {
print("保全人員通知居民包裹已送達,門牌號碼:\(doorNumber)。")
for resident in 登記的住戶 {
resident.領包裹通知(forDoorNumber: doorNumber)
}
}
Step 4: 住戶處理通知
住戶收到通知後,會判斷包裹是否屬於自己家。如果是,則會準備領取包裹:
func 領包裹通知(forDoorNumber doorNumber: String) {
if self.doorNumber == doorNumber {
print("\(name)(門牌號碼:\(doorNumber))收到包裹通知,準備磁扣到櫃檯領包裹. 📦")
}
}
完整程式碼
以下是完整的實作範例,展示了如何使用 Delegate 和 Protocol 來實現群組通訊的邏輯:
protocol 智生活APP: AnyObject {
func 領包裹通知(forDoorNumber doorNumber: String)
}
class 住戶: 智生活APP {
let name: String
let doorNumber: String
init(name: String, doorNumber: String) {
self.name = name
self.doorNumber = doorNumber
}
func 領包裹通知(forDoorNumber doorNumber: String) {
if self.doorNumber == doorNumber {
print("\(name)(門牌號碼:\(doorNumber))收到包裹通知,準備磁扣到櫃檯領包裹. 📦")
}
}
}
class 守衛 {
var 登記的住戶: [智生活APP] = []
func 登記住戶(resident: 智生活APP) {
登記的住戶.append(resident)
}
func 領包裹通知(forDoorNumber doorNumber: String) {
print("保全人員通知居民包裹已送達,門牌號碼:\(doorNumber)。")
for resident in 登記的住戶 {
resident.領包裹通知(forDoorNumber: doorNumber)
}
}
}
// 使用示例
let securityGuard = 守衛()
let resident1 = 住戶(name: "Alice", doorNumber: "A101")
let resident2 = 住戶(name: "Jason", doorNumber: "A101")
let resident3 = 住戶(name: "Jenny", doorNumber: "A101")
let resident4 = 住戶(name: "Bob", doorNumber: "A102")
securityGuard.登記住戶(resident: resident1)
securityGuard.登記住戶(resident: resident2)
securityGuard.登記住戶(resident: resident3)
securityGuard.登記住戶(resident: resident4)
securityGuard.領包裹通知(forDoorNumber: "A101")
securityGuard.領包裹通知(forDoorNumber: "A103") // 沒有對應的住戶,不會有任何通知
這個範例展示了如何透過 Delegate 和 Protocol 來處理群組通訊的場景,應用範圍包括但不限於群體通知、協同作業等。這樣的架構不僅使通信更靈活,也避免了對具體實現的過度依賴,從而提升了程式的可維護性。
透過這個群組通訊的例子,我們可以看出 Delegate 和 Protocol 如何在物件之間實現更靈活的交互,而無需強耦合。這樣的設計既簡化了程式邏輯,又提升了可擴展性。下一篇我們將繼續探討如何處理多個 Protocol 的情況,並介紹一個以動物為主題的實例。