Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
  • 第 11 章:构建可复用的协议化框架

第 11 章:构建可复用的协议化框架

11.2 协议与模块化开发的结合

模块化开发是一种将复杂系统拆分为独立、可复用模块的设计方法,能够提高代码的可维护性和团队协作效率。Swift 的协议化编程(Protocol-Oriented Programming, POP)与模块化开发天然契合,通过定义清晰的接口和行为约束,可以实现模块之间的低耦合和高内聚。本节将探讨如何将协议与模块化开发结合,设计一个模块化的框架,并以一个“通知系统”为例展示具体实现。

模块化开发与协议的优势

在模块化开发中,协议提供了以下关键支持:

  1. 接口定义:协议作为模块之间的契约,确保模块间的通信清晰且类型安全。
  2. 依赖解耦:通过依赖注入和协议抽象,模块无需直接依赖具体实现。
  3. 可替换性:模块可以通过不同的协议实现替换,增强灵活性。
  4. 测试便利:协议便于 mock 实现,简化单元测试。

设计一个模块化的通知系统

我们将设计一个通知系统框架,包含以下模块:

  • 核心模块:定义通知的发送和接收接口。
  • 存储模块:管理通知数据的持久化。
  • 展示模块:处理通知的 UI 显示。

1. 定义核心协议

核心模块通过协议定义通知系统的基本行为:

// 通知模型协议
protocol NotificationItem {
    var id: String { get }
    var title: String { get }
    var message: String { get }
}

// 通知发送者协议
protocol NotificationSender {
    func send(notification: NotificationItem)
}

// 通知接收者协议
protocol NotificationReceiver {
    func receive(notification: NotificationItem)
}

// 通知管理器协议
protocol NotificationManaging {
    func registerReceiver(_ receiver: NotificationReceiver)
    func unregisterReceiver(_ receiver: NotificationReceiver)
    func dispatch(notification: NotificationItem)
}
  • NotificationItem 定义通知的基本结构。
  • NotificationSender 和 NotificationReceiver 分别抽象发送和接收行为。
  • NotificationManaging 协调通知的分发。

2. 实现核心模块

核心模块提供通知管理器的默认实现:

class NotificationManager: NotificationManaging {
    private var receivers: [NotificationReceiver] = []
    private let sender: NotificationSender
    
    init(sender: NotificationSender) {
        self.sender = sender
    }
    
    func registerReceiver(_ receiver: NotificationReceiver) {
        receivers.append(receiver)
    }
    
    func unregisterReceiver(_ receiver: NotificationReceiver) {
        receivers.removeAll { $0 === receiver }
    }
    
    func dispatch(notification: NotificationItem) {
        sender.send(notification: notification)
        receivers.forEach { $0.receive(notification: notification) }
    }
}
  • NotificationManager 依赖一个 NotificationSender,并维护一组 NotificationReceiver。
  • dispatch 方法将通知发送并分发给所有注册的接收者。

3. 实现存储模块

存储模块负责通知的持久化,使用协议解耦存储实现:

// 通知存储协议
protocol NotificationStorage {
    func save(notification: NotificationItem)
    func loadAll() -> [NotificationItem]
}

// UserDefaults 存储实现
struct UserDefaultsNotificationStorage: NotificationStorage {
    private let defaults: UserDefaults
    private let key = "notifications"
    
    init(defaults: UserDefaults = .standard) {
        self.defaults = defaults
    }
    
    func save(notification: NotificationItem) {
        var notifications = loadAll()
        notifications.append(notification)
        let data = try? JSONEncoder().encode(notifications)
        defaults.set(data, forKey: key)
    }
    
    func loadAll() -> [NotificationItem] {
        guard let data = defaults.data(forKey: key),
              let notifications = try? JSONDecoder().decode([CodableNotification].self, from: data) else {
            return []
        }
        return notifications
    }
}

// 辅助模型,确保可编码
struct CodableNotification: NotificationItem, Codable {
    let id: String
    let title: String
    let message: String
}
  • NotificationStorage 定义存储接口,UserDefaultsNotificationStorage 是具体实现。
  • 存储模块独立于核心模块,仅通过协议交互。

4. 实现展示模块

展示模块处理通知的 UI 显示,使用协议抽象视图行为:

// 通知视图协议
protocol NotificationView: NotificationReceiver {
    func showNotification(_ notification: NotificationItem)
}

// UIKit 视图控制器实现
class NotificationViewController: UIViewController, NotificationView {
    private var notifications: [NotificationItem] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
    }
    
    func receive(notification: NotificationItem) {
        notifications.append(notification)
        showNotification(notification)
    }
    
    func showNotification(_ notification: NotificationItem) {
        let alert = UIAlertController(title: notification.title, message: notification.message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default))
        present(alert, animated: true)
    }
}
  • NotificationView 继承 NotificationReceiver,并添加显示方法。
  • NotificationViewController 是 UIKit 中的具体实现,可以替换为 SwiftUI 或其他视图。

5. 模块组合与使用

将模块组合起来,形成完整的通知系统:

// 简单通知发送者实现
struct ConsoleNotificationSender: NotificationSender {
    func send(notification: NotificationItem) {
        print("Sending notification: \(notification.title) - \(notification.message)")
    }
}

// 使用示例
let sender = ConsoleNotificationSender()
let manager = NotificationManager(sender: sender)
let storage = UserDefaultsNotificationStorage()
let viewController = NotificationViewController()

manager.registerReceiver(viewController)
manager.registerReceiver(storage)

let notification = CodableNotification(id: "1", title: "Update", message: "New version available!")
manager.dispatch(notification: notification)

// 检查存储
let savedNotifications = storage.loadAll()
print("Stored notifications: \(savedNotifications.count)")
  • 核心模块(NotificationManager)协调通知的分发。
  • 存储模块(UserDefaultsNotificationStorage)持久化通知。
  • 展示模块(NotificationViewController)显示通知。

模块化与协议的结合优势

  1. 独立性:每个模块(核心、存储、展示)独立开发和测试,仅通过协议交互。
  2. 可替换性:可以替换 NotificationSender(如用网络发送)、NotificationStorage(如用数据库)或 NotificationView(如用 SwiftUI)。
  3. 扩展性:新增模块只需实现相应协议,无需修改现有代码。
  4. 低耦合:模块之间通过协议解耦,减少直接依赖。

小结

通过将协议化编程与模块化开发结合,我们构建了一个灵活的通知系统框架。协议定义了模块间的接口,模块化设计确保了职责分离和独立性。这种方法适用于任何需要复用的框架开发,下一节将通过一个日志系统的实战案例进一步展示其实用性。

Last Updated:: 3/18/25, 4:45 PM