Swift中的面向協議程式設計

yellow超發表於2018-05-03

Swift是一門支援多程式設計正規化的程式語言,支援物件導向程式設計,面向協議程式設計,以及現在很火的函數語言程式設計(RxSwift)。而面向協議程式設計更是被apple官方甚至一些地方性的Swift大會中大力推廣(2016年在北京開的Swift開發者大會)。

其實當下的主流程式設計思想還是物件導向程式設計,但是問題在於被開發者過度使用。當然有人會反駁說,你寫一個iOS app 你首先就得繼承UIViewController吧,是! 沒錯,不依賴於Cocoa Touch進行開發是很難的。在app開發過程中,controller和view需要使用系統框架,大部分都採用物件導向程式設計方式,而model和viewModel的等等業務或是自定義部分,都應該優先考慮使用面向協議的方式程式設計,比如我們常常把網路請求的部分用協議進行封裝一個Requestable的實現,這樣當網路請求庫不好使的時候也可以輕鬆的把實現給替換掉,而不用大動干戈的到處去修改。

物件導向程式設計和麵向協議程式設計最明顯的區別在於對資料型別的抽取(抽象)上,物件導向程式設計使用類和繼承的手段,資料型別是引用型別;而面向協議程式設計使用的是遵守協議的手段,資料型別是值型別(Swift中的結構體或列舉)

##下面通過一個簡單的例子來看下面向協議程式設計的優勢體現

  • 協議和協議擴充套件 VS. 超類
  1. 超類
class BaseView {
    
    var width: CGFloat?
    var height: CGFloat?
    var color: UIColor?
    
    init(width: CGFloat, height: CGFloat, color: UIColor) {
        self.width = width
        self.height = height
        self.color = color
    }
    
    func singleTouch() {
        print("single touch -------->\(self)")
    }
    
    func doubleTouch() {
        print("double touch -------->\(self)")
    }
}
複製程式碼
  1. 協議和協議擴充套件

定義了一個view協議,並通過extension實現了方法的預設是實現

protocol ViewType {
    
    var width: CGFloat {get set}
    var height: CGFloat {get set}
    var color: UIColor {get set}
}

extension ViewType {
    
    func singleTouch() {
        print("single touch -------->\(self)")
    }
    
    func doubleTouch() {
        print("double touch -------->\(self)")
    }
}
複製程式碼

###面向協議程式設計中實現 ViewType協議

struct MyView: ViewType {
    var width: CGFloat
    var height: CGFloat
    var color: UIColor
    
    init(width: CGFloat, height: CGFloat, color: UIColor) {
        self.width = width
        self.height = height
        self.color = color
    }
}
複製程式碼
class MyOtherView: ViewType {
    var width: CGFloat
    var height: CGFloat
    var color: UIColor
    
    init(width: CGFloat, height: CGFloat, color: UIColor) {
        self.width = width
        self.height = height
        self.color = color
    }
}
複製程式碼

上面兩種方式都可以,但是我覺得實現和定義分開更易閱讀。class遵守多個協議而只能擁有一個超類。這意味著我們可以建立很多個協議以新增每個特定的功能而不是把所有功能都寫到一個巨大的類中(基類很龐大,難以維護,bug遍地);而且還可以對系統已有的協議進行擴充套件,最靈活的一點是協議可以被類、結構體和列舉遵守,而類層級被約束為類型別。協議/協議擴充套件讓我們可以在儘可能合理的地方使用值型別。

相關文章