Swift 面向協議程式設計 基礎篇 (一) 介紹

大朕東發表於2016-12-19

前言

好久沒有寫文章了,期末複習周也到了。在複習的同時順便開了一個專題,面向協議程式設計,[ 基礎篇 ],[ 進階篇 ],[ 實踐篇 ]。

介紹

首先,物件導向(OOP)大家並不陌生,蘋果的很多框架都是以這種形式進行構建的,但是,蘋果很矯情,2015年WWDC來,鼓勵使用 Value Type 值型別,也引出了這麼一個話題Protocol Oriented Programming 面向協議程式設計方式。關於值型別和引用型別,可以檢視官方文件或者這篇部落格[推薦略看一下]

OOP的發展已經很多年了,一直作為一種主流,蘋果的框架也是在一層又一層的繼承搭建起來的,但是在水果已經在不斷地強調使用Protocol了,自然有它的原因所在。

  • 在OOP中,不支援多繼承的關係,往往定義一個BaseController,再往裡面新增方法,會造成程式碼很難維護(資料)
  • 因為class是引用型別,所以可能會出現一些引用計數,引用迴圈等問題,你必須處理好這些問題。
  • 子類繼承超類的時候,需要重寫很多你並不需要的例項或者方法。

“Instead of using a class, start with a protocol”.

Swift 面向協議程式設計   基礎篇 (一) 介紹
Paste_Image.png

認識Protocol

引用蘋果官方文件的說明,Protocol定義一張藍圖,並且能被class,struct,enum 繼承。而且,最重要的是支援多繼承的關係。

A protocol defines a blueprint of methods, properties, and other requirements ... The protocol can then be adopted by a class, structure, or enumeration.

正好今早學校寵物節?,下面我們定義一個Dog的協議。

struct Person {
    var name: String
}
protocol Dog {
    var name: String { get }
    var owner: Person { get }
    var age: Int { get }
}複製程式碼

然後宣告一個struct遵循該協議

struct Husky: Dog {
    let name: String // 例項的name不能修改
    let owner: Person 
    var age: Int 
//    不需要init( ) 也不需要override
//    init(name: String, owner: Person, age: Int) {
//        self.name = name
//        self.owner = owner
//        self.age = age
//    }
}複製程式碼

協議的組合,和多繼承

我們的狗狗在寵物節是要去參加比賽的,所以我們定義一個Playable的協議

protocol Playable {
    var GameName: String { get }
    func playGame()
}複製程式碼

我們知道在OOP的世界裡,是不支援多繼承的關係的。Protocol的出現直接修補了這個DrawBack。

我們組合一下兩個協議

protocol DogCanPlay: Dog, Playable { }複製程式碼

接下來宣告一個struct遵循這個協議,這樣這個struct就擁有了這兩個協議的所有屬性和方法,而且,編譯器還會告訴你,你缺少哪個屬性,哪個方法沒有宣告,非常方便。

struct PlayableDog: DogCanPlay {
    var name: String
    var owner: Person
    var age: Int
    func playGame() {
        print("biubiubiu~")
    }
    var GameName: String
}複製程式碼

協議的組合原理也是多繼承的關係,上面的程式碼也可以這麼寫

struct PlayableDog: Dog, Playable {
    var name: String
    var owner: Person
    var age: Int
    func playGame() {
        print("biubiubiu~")
    }
    var GameName: String
}複製程式碼

協議的擴充套件

不得不說,自Swift 2.0後,協議擴充套件【Protocol Extension】的出現,讓面向協議程式設計更加地powerful,強力推薦這個WWDC Session

extension DogCanPlay {
    func playGame() { //  為協議新增預設實現
        print("biubiu~~")
    }
    func loseGame() {   //新增額外方法
        print("??")
    }
}複製程式碼

由於新增了預設實現,struct的定義就可以省去了playGame( )

struct Husky: DogCanPlay {
    var name: String
    var owner: Person
    var age: Int
    var GameName: String
}複製程式碼

例項一個變數試試~

var myDog = Husky(name: "小黃", owner: Person(name: "大東"), age: 4, GameName: "接飛盤")
myDog.playGame() // biubiu~
myDog.loseGame() // ??複製程式碼

協議的多型

我們知道,OOP有多型的特徵,在POP裡,也支援?

struct Dalmatian: DogCanPlay {
    var name: String
    var owner: Person
    var age: Int
    var GameName: String
}複製程式碼

建立兩個例項

let myDog = Husky(name: "小黃", owner: Person(name: "大東"), age: 4, GameName: "接飛盤")
let otherDog = Dalmatian(name: "達爾馬提亞狗", owner: Person(name: "洪**"), age: 4, GameName: "賽跑")複製程式碼

??

var competitionDog: [DogCanPlay] = [myDog, otherDog]
for dog in competitionDog {
    print(dog.name) 
     //小黃
     //達爾馬提亞狗
}複製程式碼

總結

基礎篇就介紹到這。往後,我會介紹protocol中where語法的使用,還有POP在UIKit的實踐。喜歡請點個贊?
ARC and Memory Management in Swift
Introducing Protocol-Oriented Programming in Swift 3

Swift 面向協議程式設計   基礎篇 (一) 介紹
Think Different

相關文章