import UIKit
import Foundation
/面向協定程式設計*****/
/// POP就是通過協定擴充,協定繼承和協定組合的方式來設計需要編寫的代碼
/// 協定擴充 Protocol Extensions
/// 協定繼承
/// 協定組合
/// Swift中,值類型優先于類,值類型可以從協定繼承,設定支援從多個協定繼承,是以,使用POP讓值類型成為了Swift中的一等公民
/// Protocol Extensions
/// 提供協定方法的預設實作和協定屬性的預設值,進而使它們成為可選;符合協定的類型可以提供自己的實作,也可以使用預設的實作。
/// 添加協定中未聲明的附加方法實作,并且實作協定的任何類型都可以使用到這些附加方法。這樣就可以給遵循協定的類型添加特定的方法。
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)
/// Protocol Inheritance
/// 協定可以從其他協定繼承,然後在它繼承的需求之上添加功能,是以可以提供更細粒度和更靈活的設計。
protocol Persistable: Entity {
func write(instance: Entity, to filePath: String)
init?(by uid: String)
}
struct InMemoryEntity: Entity {
var name: String
}
struct PersistableEntity: Persistable {
func write(instance: Entity, to filePath: String) { }
init?(by uid: String) {
/// // try to load from the filesystem based on id
return nil
}
var name: String
}
/// Protocol Composition
/// 類、結構體和枚舉可以符合多個協定,它們可以采用多個協定的預設實作。這在概念上類似于多繼承。這種組合的方式不僅比将所有需要的功能壓縮到一個基類中更靈活,而且也适用于值類型
struct MyEntity: Entity, Equatable, CustomStringConvertible {
/// CustomStringConvertible
public var description: String {
return “MyEntity: (name)”
}
/// Equatable
/// lhs:left hand side
/// rhs:right hand side
public static func == (lhs: MyEntity, rhs: MyEntity) -> Bool {
return lhs.name == rhs.name
}
var name: String
}
let entity1 = MyEntity(name: “42”)
print(entity1)
let entity2 = MyEntity(name: “42”)
assert(entity1 == entity2, “Entities shall be equal”)
protocol TheProtocol {
/// method is defined in protocol
func method1()
}
extension TheProtocol {
/// method1 is defined in protocol
func method1() {
print(“Called method1 from TheProtocol”)
}
/// Extention添加協定中未聲明的附加方法實作
/// method2 is not defined in protocol
func method2() {
print(“Called method2 from TheProtocol”)
}
}
struct Struct1: TheProtocol {
/// 動态類型實作 method1
func method1() {
print(“called method1 from Struct1”)
}
/// 動态類型實作 method2
func method2() {
print(“called method2 from Struct1”)
}
}
/// 推斷類型為 動态類型 執行動态類型實作方法
let s1 = Struct1()
s1.method1()
s1.method2()
print("\n-----------------\n")
/// 推斷類型為 協定類型
let s2: TheProtocol = Struct1()
/// method1 在協定中有定義 調用Struct1的動态類型實作方法
s2.method1()
/// method2 在協定中無定義 在extention的實作 調用TheProtocol的extention預設實作方法
s2.method2()
print("\n-----------------\n")