OOP和POP

面向对象编程(Object Oriented Programming, OOP)是我们使用OC的核心,也是我们Swift开发的主要编程思想,然后在2015年WWDC之后,苹果第一次提出了Swift的面向协议编程 (Protocol Oritented Programming, POP), 一个全新的编程范式。

OOP(Object Oriented Programming, 面向对象编程)

OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间的传递。

面向对象的三大特性:

  • 封装

    即将客观事物封装称抽象的类,通过访问权限控制暴漏接口,但是把具体实现隐藏起来。具有可读性、科维护性、可扩展性的特点

  • 多态

    多态是指一个类实例的相同方法在不同情形下有不同的表现形式,子类可以重写父类的方法

  • 继承

    可以使用父类的所有功能,无需重新编写原来的类的方法,同时可以进行扩展。是一种复用的技术。

    OC和Swift中只能单继承,不能多继承

OOP的优点

  1. 重用性
  2. 灵活性
  3. 扩展性

OOP的缺点

  1. 隐式共享:Class是引用类型,容易造成多处引用
  2. 冗长的父类
  3. 很难在不同继承关系的类里共用代码(横切关注点Cross-Cutting Concerns)
  4. 动态派发的安全性

POP(Protocol Oriented Programming, 面向协议编程)

“所谓协议,就是一组属性和/或方法的定义,而如果某个具体类型想要遵守一个协议,那它需要实现这个协议所定义的所有这些内容。协议实际上‘’关于实现的约定’ “

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
protocol Greetable {
var name : String{get}
func greet()
}
struct Person : Greetable {
let name: String
func greet() {
print("Hello, \(name)")
}
}
struct Cat: Greetable {
let name: String
func greet() {
print("meow ~ \(name)")
}
}
let array: [Greetable] = [Person(name: "Don"),
Cat(name: "xiao")]
for obj in array{
obj.greet()
}

上面的例子体现了协议在解决动态派发时的过程,如果是两个不继承的类实现相同方法呢,Swift中协议的扩展可以提供默认的实现,如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
protocol Greetable {
var name : String{get}
func greet()
}
extension Greetable{ // 协议扩展,可以提供默认的实现,这也是Swift成为一门协议优先的语言
func greet() {
print("Hello, \(name)")
}
}
struct Person : Greetable {
let name: String
}
struct Cat: Greetable {
let name: String
}
let array: [Greetable] = [Person(name: "Don"),
Cat(name: "xiao")]
for obj in array{
obj.greet()
}

POP有哪些优势

  1. 更加灵活:相比于冗长的父类,可以使用协议及其扩展将默认实现移到协议中
  2. 减少依赖:相比于OOP,更加关注于实现

参考资料:

  1. Protocol-Oriented Programming in Swift
  2. 面向协议的编程与Cocoa的邂逅(上)
  3. 面向协议的编程与Cocoa的邂逅(下)