4-1.【协议导向编程】什么是协议导向编程(POP),它解决了传统面向对象设计中的哪些问题?

23 阅读2分钟

1️⃣ 什么是协议导向编程(POP)

协议导向编程 是 Swift 提出的编程范式,它的核心思想是:

  • 通过协议(protocol)定义接口和行为,而不是依赖类继承。
  • 通过协议扩展(protocol extensions)提供默认实现,减少重复代码。
  • 关注行为组合而非继承层级,强调“能力”的组合而不是类的层级关系。

简单理解:

在 POP 中,我们关注对象 能做什么(行为),而不是它 是什么(类型/类继承)。


Swift 中的协议示例

protocol Flyable {
    func fly()
}

protocol Swimmable {
    func swim()
}

// 给 Flyable 提供默认实现
extension Flyable {
    func fly() {
        print("I can fly!")
    }
}

// 使用协议组合
struct Bird: Flyable, Swimmable {
    func swim() {
        print("I can swim too!")
    }
}

let duck = Bird()
duck.fly()   // 输出: I can fly!
duck.swim()  // 输出: I can swim too!

✅ 这里你可以看到:

  • 没有继承自基类。
  • 通过协议组合实现多种能力。
  • 默认实现避免重复代码。

2️⃣ POP 解决了传统 OOP 的哪些问题

在传统面向对象编程(OOP)中,我们通常使用 类继承 来复用代码:

class Animal { ... }
class Bird: Animal { ... }
class Duck: Bird { ... }

OOP 的局限

  1. 继承层级僵化

    • 类只能单继承(Swift 中类也只支持单继承)。
    • 行为复用受限。
    • 如果想让一个类同时拥有多种能力(fly、swim、run),继承树会变得复杂。
  2. 代码复用困难

    • 父类提供通用方法,但子类可能需要修改。
    • 多个不相关类要重复实现相同功能。
  3. 类型耦合强

    • 子类依赖父类,导致灵活性下降。
    • 改变父类可能影响整个继承链。

POP 的优势

问题POP 的解决方案
单继承限制协议可以任意组合,轻松实现多能力组合(多重“继承”效果)
代码重复协议扩展提供默认实现,避免重复实现
耦合性强类型依赖协议接口而非具体类,实现低耦合
灵活性差POP 强调行为组合,可在不改变继承关系的前提下扩展功能
测试难度大使用协议作为依赖(依赖注入),单元测试更容易模拟/mock

Swift POP 的典型实践

  1. 使用协议定义能力(Abilities)

    • Flyable, Swimmable, Runnable 等。
  2. 协议扩展提供默认实现

    • 避免每个类型都重复实现。
  3. 通过协议组合创建对象

    • 组合多种能力而不依赖继承层级。
  4. 依赖抽象而非具体类型

    • 代码更灵活,可测试性高。

总结

协议导向编程(POP) 的核心思想是:

“面向协议编程,而不是面向类编程”
通过协议组合和扩展,实现行为复用和灵活的类型组合,从而解决了传统 OOP 的继承僵化、代码重复、耦合度高等问题。

Swift 官方甚至强调:

Swift 是协议导向语言,而不是类继承语言