天天看點

協定程式設計 Swift中,值類型優先于類

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")