4-27.【协议导向编程】如何结合 POP 和泛型,实现跨模块可复用的业务逻辑?

2 阅读2分钟

一、核心原理

  1. 协议(Protocol)

    • 描述业务能力或契约 → 不关心具体类型
    • 模块间只依赖协议,降低耦合
  2. 泛型(Generic)

    • 在编译期绑定类型 → 静态派发,高性能
    • 支持值类型 + class 类型 → 灵活
  3. 协议 + 泛型 = 零开销抽象 + 可复用逻辑

    • 高层模块使用协议约束泛型
    • 低层模块实现协议 → 可跨模块替换
  4. 默认实现(Protocol Extension)

    • 提供模板 / 公共逻辑 → 不破坏多态
    • 类型可覆盖 → 灵活扩展

二、设计策略

  1. 定义能力协议

    • 协议只描述核心方法
    • 放在公共模块,可供多个业务模块依赖
  2. 扩展协议提供默认实现

    • 工具方法、模板逻辑、复用逻辑
    • 类型可以覆盖 → 定制行为
  3. 业务逻辑使用泛型约束协议

    • 核心逻辑高性能 → 静态派发
    • 支持多种模块实现 → 跨模块复用
  4. 模块间只依赖协议,不依赖具体类型

    • 保证低耦合
    • 测试可注入 mock 类型

三、Swift 示例:跨模块支付逻辑

假设有 支付模块(PaymentModule)和 订单模块(OrderModule),我们希望支付逻辑可复用。

1️⃣ 公共协议模块(PaymentProtocolModule)

protocol PaymentProcessor {
    func pay(amount: Double)
}

// 默认模板逻辑
extension PaymentProcessor {
    func execute(amount: Double) {
        preProcess()
        pay(amount: amount)
        postProcess()
    }
    
    func preProcess() { print("Default pre-processing") }
    func postProcess() { print("Default post-processing") }
}
  • 模块间依赖协议
  • 提供模板方法 → 可复用

2️⃣ 订单模块使用泛型约束协议

struct Order<Processor: PaymentProcessor> {
    var processor: Processor
    var amount: Double
    
    func checkout() {
        processor.execute(amount: amount) // 静态派发,零开销
    }
}
  • 核心逻辑 checkout() 不依赖具体支付实现
  • 泛型约束 → 高性能

3️⃣ 支付模块具体实现

struct CreditCardProcessor: PaymentProcessor {
    func pay(amount: Double) {
        print("Processing credit card payment: (amount)")
    }
}

struct ApplePayProcessor: PaymentProcessor {
    func pay(amount: Double) {
        print("Processing Apple Pay payment: (amount)")
    }
}

4️⃣ 跨模块复用

let creditOrder = Order(processor: CreditCardProcessor(), amount: 100)
creditOrder.checkout()
// 输出:
// Default pre-processing
// Processing credit card payment: 100
// Default post-processing

let appleOrder = Order(processor: ApplePayProcessor(), amount: 200)
appleOrder.checkout()
// 输出:
// Default pre-processing
// Processing Apple Pay payment: 200
// Default post-processing

✅ 特点:

  • 订单模块不依赖支付模块具体类型 → 低耦合
  • 核心逻辑静态派发 → 高性能
  • 模板方法复用 → 跨模块逻辑复用
  • 新支付方式只需新增 conforming 类型 → 可扩展

四、工程实践策略

策略说明
公共协议模块提供跨模块契约和模板方法
默认实现提供可复用业务逻辑,类型可覆盖
泛型约束协议静态派发 → 零开销抽象
模块间依赖协议保持低耦合,支持 mock 测试
类型组合能力struct/class conform 多协议 → 多功能复用
扩展能力新模块直接 conform 协议,无需改现有代码

五、设计口诀

“协议抽象能力 → 模块间依赖协议;
模板方法提供复用 → 默认实现;
泛型约束协议 → 核心静态派发高性能;
类型 conform → 跨模块扩展能力。”