inside every large program, there is a small program trying to get out.
POP(面向协议编程)将复杂的多层继承结构,替换为小的,简单的,可以结合的结构。
1.协议
协议是描述某些事物具有的属性和方法的一种方式。类型可以采用或者遵循协议。
protocol Identifiable {
var id: String {get set}
}
struct User: Identifiable {
var id: String
}
func displayID(thing: Identifiable) {
print("ID is \(thing.id)")
}
我们定义了一个Identifiable协议,协议要求所有符合条件的类型具有一个id,可以读写的字符串。
我们无法创建协议的实例,但我们可以创建一个符合它的结构。
最后编写了一个接受符合Identifiable对象的函数。
Swift为什么需要协议?
先举一个例子
struct Book {
var name: String
}
func buy(_ book: Book) {
print("I'm buying \(book.name)")
}
我们编写一个buy函数,问题在于此函数,只能接收Book对象。
如果有其它类型,则需要创建类似的同样buy函数,而协议允许我们的操作笼统的对待数据。
protocol Purchaseable {
var name: String { get set }
}
我们创建一个适用于我们的功能的协议。
struct Book: Purchaseable {
var name: String
var author: String
}
struct Car: Purchaseable {
var name: String
var manufacturer: String
}
同样其它的结构也可以遵循此协议。
func buy(_ item: Purchaseable) {
print("I'm buying \(item.name)")
}
重写的buy函数,可以接受任何符合Purchaseable协议的类型。
2.协议继承
和类一样,协议也可以继承。
和类不同的是,协议可以继承多个协议。
我们创建一个Employee协议,整合多个协议。
protocol Payable {
func calculateWages() -> Int
}
protocol NeedsTraining {
func study()
}
protocol HasVacation {
func takeVacation(days: Int)
}
protocol Employee: Payable, NeedsTraining, HasVacation { }
什么时候使用协议继承?
protocol Computer {
var price: Double { get set }
var weight: Int { get set }
var cpu: String { get set }
var memory: Int { get set }
var storage: Int { get set }
}
protocol Laptop {
var price: Double { get set }
var weight: Int { get set }
var cpu: String { get set }
var memory: Int { get set }
var storage: Int { get set }
var screenSize: Int { get set }
}
这两个协议有很多的重复项,如果将协议分解成较小的部分,然后重新组装,它将更加简单和灵活。
protocol Product {
var price: Double { get set }
var weight: Int { get set }
}
protocol Computer: Product {
var cpu: String { get set }
var memory: Int { get set }
var storage: Int { get set }
}
protocol Laptop: Computer {
var screenSize: Int { get set }
}
3.扩展
扩展给现有类型添加方法,以便执行不是设计执行的操作。
比如给int添加一个squared()方法。
extension Int {
func squared() -> Int {
return self * self
}
}
let number = 8
number.squared()
swift不允许在扩展中添加存储属性,必须用计算属性。例如,添加isEven计算属性。
extension Int {
var isEven: Bool {
return self % 2 == 0
}
}
什么时候使用扩展?
扩展可以向类、结构添加功能,有助于修改我们不拥有的类型,例如Apple或其他人编写的类型。
扩展对于组织我们的代码也很有用,一致性分组和目的分组。
一致性分组,将协议添加到扩展中,在扩展中添加所有必须的方法。
目的性分组,创建扩展来执行特定的任务,使得处理大型类型很容易。例如,专门处理该类型的加载和保存的扩展。
整齐的拆分,使得它们更容易理解。
网友评论