1. Swift - the First POP Language
在WWDC15上盹牧,蘋果宣布Swift是世界上第一門面向協(xié)議編程(POP)語言。
2. 何為POP
實際上,POP就是通過協(xié)議擴展归露,協(xié)議繼承和協(xié)議組合的方式來設計需要編寫的代碼。
在Swift中斤儿,值類型優(yōu)先于類剧包。然而,面向對象的概念不能很好地與結構體和枚舉一起工作: 因為結構體和枚舉不能夠被繼承雇毫。因此玄捕,作為面向對象的一大特征—繼承就不能夠應用于值類型了踩蔚。
Sequences and collections in the standard library use value semantics, which makes it easy to reason about your code. Every variable has an independent value, and references to that value aren’t shared. For example, when you pass an array to a function, that function can’t accidentally modify the caller’s copy of the array.
值類型可以從協(xié)議繼承棚放,設置支持從多個協(xié)議繼承,因此馅闽,使用POP讓值類型成為了Swift中的一等公民飘蚯。
3. Protocol 一元復始,萬象更新
假設現(xiàn)在需要定義公共行為福也,如果使用類一般來說會在父類中定義功能局骤,子類依賴繼承可以得到父類的特性,或者自己重寫該方法添加其他行為暴凑。這其實是一個好的選擇峦甩,但是當方法越來越多或是需要實現(xiàn)在不同的類的功能,這個時候又需要給父類重新添加方法现喳,或者是干脆重新創(chuàng)建類凯傲。
舉個??:
假設:B、C 繼承自 A嗦篱,B1冰单、B2繼承自 B,C1灸促、C2繼承自 C
如果你發(fā)現(xiàn) B1 和 C2 具有某些共同特性诫欠,
在OC中如果完全使用繼承的做法是找到 B1 和 C2 的最近祖先涵卵,也就是 A,然后在 A 中添加一段代碼荒叼。于是還得重寫 B2 和 C1轿偎,禁用這個方法。
而協(xié)議通過描述實現(xiàn)類型應該實現(xiàn)什么來抽象建模被廓。因為可以實現(xiàn)多協(xié)議贴硫,一種類型可以被拆分為若干個抽象,這樣的話就可以將大的功能細化伊者。
4. 分守要津
1. Protocol Extensions
- 提供協(xié)議方法的默認實現(xiàn)和協(xié)議屬性的默認值英遭,從而使它們成為可選;符合協(xié)議的類型可以提供自己的實現(xiàn)亦渗,也可以使用默認的實現(xiàn)挖诸。
- 添加協(xié)議中未聲明的附加方法實現(xiàn),并且實現(xiàn)協(xié)議的任何類型都可以使用到這些附加方法法精。這樣就可以給遵循協(xié)議的類型添加特定的方法多律。
protocol Entity {
var name: String {get set}
static func uid() -> String
}
extension Entity {
static func uid() -> String {
return UUID().uuidString
}
}
struct Order: Entity {
var name: String
let uid: String = Order.uid()
}
let order = Order(name: "My Order")
print(order.uid)
2. Protocol Inheritance
協(xié)議可以從其他協(xié)議繼承,然后在它繼承的需求之上添加功能搂蜓,因此可以提供更細粒度和更靈活的設計狼荞。
protocol Persistable: Entity {
func write(instance: Entity, to filePath: String)
init?(by uid: String)
}
struct InMemoryEntity: Entity {
var name: String
}
struct PersistableEntity: Persistable {
var name: String
func write(instance: Entity, to filePath: String) { // ...
}
init?(by uid: String) {
// try to load from the filesystem based on id
}
}
3. Protocol Composition
類、結構體和枚舉可以符合多個協(xié)議帮碰,它們可以采用多個協(xié)議的默認實現(xiàn)相味。這在概念上類似于多繼承。這種組合的方式不僅比將所有需要的功能壓縮到一個基類中更靈活殉挽,而且也適用于值類型丰涉。
struct MyEntity: Entity, Equatable, CustomStringConvertible {
var name: String
// Equatable
public static func ==(lhs: MyEntity, rhs: MyEntity) -> Bool {
return lhs.name == rhs.name
}
// CustomStringConvertible
public var description: String {
return "MyEntity: \(name)"
}
}
let entity1 = MyEntity(name: "42")
print(entity1)
let entity2 = MyEntity(name: "42")
assert(entity1 == entity2, "Entities shall be equal")
5. 浮想聯(lián)翩
以下代碼會輸出什么???
protocol TheProtocol {
func method1()
}
extension TheProtocol {
func method1() {
print("Called method1 from TheProtocol")
}
func method2() {
print("Called method2 from TheProtocol")
}
}
struct Struct1: TheProtocol {
func method1() {
print("called method1 from Struct1")
}
func method2() {
print("called method2 from Struct1")
}
}
let s1 = Struct1()
s1.method1()
s1.method2()
print("\n-----------------\n")
let s2:TheProtocol = Struct1()
s2.method1()
s2.method2()
print("\n-----------------\n")
結果參考流程圖:
參考文獻:
Protocol Oriented Programming in Swift
Swift protocol extension method dispatch
Protocol Oriented Programming in Swift