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 的局限
-
继承层级僵化
- 类只能单继承(Swift 中类也只支持单继承)。
- 行为复用受限。
- 如果想让一个类同时拥有多种能力(fly、swim、run),继承树会变得复杂。
-
代码复用困难
- 父类提供通用方法,但子类可能需要修改。
- 多个不相关类要重复实现相同功能。
-
类型耦合强
- 子类依赖父类,导致灵活性下降。
- 改变父类可能影响整个继承链。
POP 的优势
| 问题 | POP 的解决方案 |
|---|---|
| 单继承限制 | 协议可以任意组合,轻松实现多能力组合(多重“继承”效果) |
| 代码重复 | 协议扩展提供默认实现,避免重复实现 |
| 耦合性强 | 类型依赖协议接口而非具体类,实现低耦合 |
| 灵活性差 | POP 强调行为组合,可在不改变继承关系的前提下扩展功能 |
| 测试难度大 | 使用协议作为依赖(依赖注入),单元测试更容易模拟/mock |
Swift POP 的典型实践
-
使用协议定义能力(Abilities)
Flyable,Swimmable,Runnable等。
-
协议扩展提供默认实现
- 避免每个类型都重复实现。
-
通过协议组合创建对象
- 组合多种能力而不依赖继承层级。
-
依赖抽象而非具体类型
- 代码更灵活,可测试性高。
总结
协议导向编程(POP) 的核心思想是:
“面向协议编程,而不是面向类编程”
通过协议组合和扩展,实现行为复用和灵活的类型组合,从而解决了传统 OOP 的继承僵化、代码重复、耦合度高等问题。
Swift 官方甚至强调:
Swift 是协议导向语言,而不是类继承语言。