第四周第一天

第四周第一天

協(xié)議,協(xié)議的語法

protocol Flyable {
    func fly()
}

protocol Fightable {
    func fight()
}

協(xié)議是方法的集合(計算屬性相當(dāng)于就是方法)
// 可以把看似不相關(guān)的對象的公共行為放到一個協(xié)議中
// 協(xié)議在Swift開發(fā)中大致有三種作用:
// 1. 能力 - 遵循了協(xié)議就意味著具備了某種能力
// 2. 約定 - 遵循了協(xié)議就一定要實(shí)現(xiàn)協(xié)議中的方法
// 3. 角色 - 一個類可以遵循多個協(xié)議, 一個協(xié)議可以被多個類遵循, 遵循協(xié)議就意味著扮演了某種角色, 遵循多個協(xié)議就意味著可以扮演多種角色
// Swift中的繼承是單一繼承(一個類只能有一個父類), 如果希望讓一個類具備多重能力可以使用協(xié)議來實(shí)現(xiàn)(C++里面是通過多重繼承來實(shí)現(xiàn)的, 這是一種非常狗血的做法)
協(xié)議的繼承

class Boxer: Fightable {
    @objc func fight() {
        print("正在進(jìn)行格斗.")
    }
}
class Bird: Flyable {

    func fly() {
        print("鳥兒扇動翅膀飛行.")
    }
}
class Airplane: Flyable {
    func fly() {
        print("飛機(jī)依靠空氣動力學(xué)原理飛行.")
    }
}

協(xié)議的拓展也可以說協(xié)議的默認(rèn)實(shí)現(xiàn)當(dāng)在類中沒有實(shí)現(xiàn)這個方法默認(rèn)實(shí)現(xiàn)的方法
協(xié)議擴(kuò)展 - 可以在協(xié)議擴(kuò)展中給協(xié)議中的方法提供默認(rèn)實(shí)現(xiàn)
也就是說如果某個類遵循了協(xié)議但是沒有實(shí)現(xiàn)這個方法就直接使用默認(rèn)實(shí)現(xiàn)
那么這個方法也就相當(dāng)于是一個可選方法(可以實(shí)現(xiàn)也可以不實(shí)現(xiàn))


extension Fightable {
    func fight() {
        print("正在打架")
    }
}

依賴倒轉(zhuǎn)原則(面向協(xié)議編程)

  1. 聲明變量的類型時應(yīng)該盡可能使用協(xié)議類型
  2. 聲明方法參數(shù)類型時應(yīng)該盡可能使用協(xié)議類型
  3. 聲明方法返回類型時應(yīng)該盡可能使用協(xié)議類型
    協(xié)議的組合
let array: [protocol<Flyable, Fightable>] = [
    // Rocket(),
    // Bird(),
    Superman(),
    // Boxer()
    // Airplane()
]
//只有同時滿足兩個協(xié)議的類才可以
for obj in array {
    obj.fly()
    obj.fight()
}

協(xié)議中全是抽象概念(只有聲明沒有實(shí)現(xiàn)) 遵循協(xié)議的類可以各自對協(xié)議中的計算屬性和方法給出自己的實(shí)現(xiàn)版本 這樣當(dāng)我們面向協(xié)議編程時就可以把多態(tài)的優(yōu)勢發(fā)揮到淋漓盡致 可以寫出更通用更靈活的代碼(符合開閉原則)

實(shí)現(xiàn)開閉原則最關(guān)鍵有兩點(diǎn):

  1. 抽象是關(guān)鍵(在設(shè)計系統(tǒng)的時候一定要設(shè)計好的協(xié)議);
  2. 封裝可變性(橋梁模式 - 將不同的可變因素封裝到不同的繼承結(jié)構(gòu)中)

接口(協(xié)議)隔離原則: 協(xié)議的設(shè)計要小而專不要大而全
協(xié)議的設(shè)計也要高度內(nèi)聚

protocol Shape {
    var perimeter: Double { get }
    var area: Double { get }
    func draw()
}
class Triangle: Shape {
    var a: Double
    var b: Double
    var c: Double
    
    init(a: Double, b: Double, c: Double) {
        assert(a + b > c && b + c > a && a + c > b, "不能構(gòu)成三角形")
        self.a = a
        self.b = b
        self.c = c
    }
    
    var perimeter: Double {
        get { return a + b + c }
    }
    
    var area: Double {
        get {
            let half = perimeter / 2
            return sqrt(half * (half - a) * (half - b) * (half - c))
        }
    }
    
    func draw() {
        print("△")
    }
    
}

協(xié)議的應(yīng)用

#### //圖書類的定義
import Foundation

/// 圖書
class Book {
    var name: String
    var price: Double
    var type: String
    
    // 四人幫設(shè)計模式 - 策略模式
    var strategy: DiscountStrategy?
    
    /**
     初始化方法
     - parameter name:  書名
     - parameter price: 價格
     - parameter type:  類型
     */
    init(name: String, price: Double, type: String) {
        self.name = name
        self.price = price
        self.type = type
    }
    
    /// 減多少錢
    var discountValue: Double {
        get {
            if let s = strategy {
                return s.discount(price)
            }
            else {
                return 0
            }
        }
    }
    
    /// 折后價格
    var discountedPrice: Double {
        get { return price - discountValue }
    }
}


#### //寫協(xié)議部分
import Foundation

/**
 *  打折策略協(xié)議
 */
protocol DiscountStrategy {
    
    /**
     計算折扣
     - parameter price: 原價
     - returns: 折扣的金額
     */
    func discount(price: Double) -> Double
}

/// 百分比折扣策略
class PercentageDiscount: DiscountStrategy {
    var percentage: Double
    
    init(percentage: Double) {
        self.percentage = percentage
    }
    
    func discount(price: Double) -> Double {
        return price * (1 - percentage)
    }
}

// 固定金額折扣策略
class FixedDiscount: DiscountStrategy {
    var fixedMoney: Double
    
    init(fixedMoney: Double) {
        self.fixedMoney = fixedMoney
    }
    
    func discount(price: Double) -> Double {
        return price >= fixedMoney ? fixedMoney : 0
    }
}

// 分段折后策略
class SegmentedDiscount: DiscountStrategy {
    
    func discount(price: Double) -> Double {
        if price < 20 {
            return 0
        }
        else if price < 50 {
            return 3
        }
        else if price < 100 {
            return 10
        }
        else {
            return 30
        }
    }
}
#### //實(shí)現(xiàn)和調(diào)用部分

import Foundation

let booksArray = [
    Book(name: "C語言程序設(shè)計", price: 24.0, type: "計算機(jī)"),
    Book(name: "名偵探柯南", price: 98.5, type: "漫畫"),
    Book(name: "Swift從入門到住院", price: 35.8, type: "計算機(jī)"),
    Book(name: "黃岡數(shù)學(xué)密卷", price: 34.2, type: "教材"),
    Book(name: "中國股市探秘", price: 58.5, type: "金融")
]

let discountDict: [String: DiscountStrategy] = [
    "計算機(jī)": PercentageDiscount(percentage: 0.78),
    "教材": PercentageDiscount(percentage: 0.85),
    "漫畫": SegmentedDiscount(),
    "科普": FixedDiscount(fixedMoney: 2)
]

var totalPrice = 0.0
var totalDiscount = 0.0
for book in booksArray {
    if let strategy = discountDict[book.type] {
        book.strategy = strategy
    }
    print("《\(book.name)》原價: ¥\(book.price)元")
    print("《\(book.name)》折后價: ¥\(book.discountedPrice)元")
    totalPrice += book.discountedPrice
    totalDiscount += book.discountValue
}

print(String(format: "總計: ¥%.1f元", totalPrice))
print(String(format: "為您節(jié)省了: ¥%.1f元", totalDiscount))


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,554評論 19 139
  • 1.項(xiàng)目經(jīng)驗(yàn) 2.基礎(chǔ)問題 3.指南認(rèn)識 4.解決思路 ios開發(fā)三大塊: 1.Oc基礎(chǔ) 2.CocoaTouch...
    扶光啟玄閱讀 5,204評論 0 13
  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young閱讀 4,194評論 1 10
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,055評論 0 9
  • 在工作,戀愛,以及種種方面我們總會處于被動的局面中。矛盾與焦慮也會隨之產(chǎn)生。這個時候你要如何去做? 當(dāng)上司要求你加...
    城中聽雨閱讀 1,110評論 4 6

友情鏈接更多精彩內(nèi)容