100 Days of SwiftUI

100 Days of SwiftUI - Day 11 Pro

2020-10-13  本文已影响0人  星星星宇

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或其他人编写的类型。
扩展对于组织我们的代码也很有用,一致性分组和目的分组。
一致性分组,将协议添加到扩展中,在扩展中添加所有必须的方法。
目的性分组,创建扩展来执行特定的任务,使得处理大型类型很容易。例如,专门处理该类型的加载和保存的扩展。
整齐的拆分,使得它们更容易理解。

上一篇 下一篇

猜你喜欢

热点阅读