swift:面向?qū)ο蟆⒚嫦蚝瘮?shù)哩治、面向協(xié)議編程

一秃踩、面向?qū)ο?/h4>

傳統(tǒng)的面向?qū)ο箝_發(fā)思維方式是將類中實現(xiàn)的相似方法抽取出來,接著放入一個Base類业筏,然后繼承于Base類后各個類即可找擁有相同的方法憔杨,不用再一個個手動實現(xiàn)。
具體代碼請參考前面分析斗魚的文章蒜胖。傳送門

二消别、面向函數(shù)

Swift 支持 map, reduce, filter, flatmap 這類去除中間狀態(tài)、數(shù)學(xué)函數(shù)式的方法台谢,更加強(qiáng)調(diào)運(yùn)算結(jié)果而不是中間過程寻狂,所以我們也說Swift是面向函數(shù)編程。

三朋沮、面向協(xié)議(POP)

1蛇券、OC和Swift的面向協(xié)議的區(qū)別

OC無法做到面向協(xié)議開發(fā),而Swift可以,因為Swift可以做到協(xié)議方法的具體實現(xiàn)怀读,而OC不行诉位。面向協(xié)議開發(fā)的核心是:模塊化(組件化)。
注意:swift可以做到協(xié)議方法的具體實現(xiàn)菜枷。也就是說苍糠,聲明協(xié)議方法之后,擴(kuò)展extension該協(xié)議啤誊,然后實現(xiàn)該協(xié)議方法岳瞭。讓類遵守該代理,然后這個類就可以直接調(diào)用協(xié)議的方法了蚊锹。
注意兩點:
a.protocol中可以聲明變量瞳筏,方便在協(xié)議方法中使用。
b.協(xié)議方法的具體實現(xiàn)需要在extension中來實現(xiàn)牡昆。

示例如下:

  • 聲明協(xié)議
protocol NetworkToolProtocol {
    // MARK: - --------------------------------- 首頁 home  ---------------------------------
    // MARK: 首頁頂部新聞標(biāo)題的數(shù)據(jù)
    static func loadHomeNewsTitleData(completionHandler: @escaping (_ newsTitles: [HomeNewsTitle]) -> ())
    // MARK: 首頁頂部導(dǎo)航欄搜索推薦標(biāo)題內(nèi)容
    static func loadHomeSearchSuggestInfo(_ completionHandler: @escaping (_ searchSuggest: String) -> ())
    // MARK: 獲取首頁姚炕、視頻、小視頻的新聞列表數(shù)據(jù)
    static func loadApiNewsFeeds(category: String, ttFrom: TTFrom, _ completionHandler: @escaping (_ maxBehotTime: TimeInterval, _ news: [NewsModel]) -> ())
}
  • 實現(xiàn)協(xié)議
extension NetworkToolProtocol {
    // MARK: - --------------------------------- 首頁 home  ---------------------------------
    /// 首頁頂部新聞標(biāo)題的數(shù)據(jù)
    /// - parameter completionHandler: 返回標(biāo)題數(shù)據(jù)
    /// - parameter newsTitles: 首頁標(biāo)題數(shù)組
    static func loadHomeNewsTitleData(completionHandler: @escaping (_ newsTitles: [HomeNewsTitle]) -> ()) {
        let url = BASE_URL + "/article/category/get_subscribed/v1/?"
        let params = ["device_id": device_id,
                      "iid": iid]
        Alamofire.request(url, parameters: params).responseJSON { (response) in
            // 網(wǎng)絡(luò)錯誤的提示信息
            guard response.result.isSuccess else { return }
            if let value = response.result.value {
                let json = JSON(value)
                guard json["message"] == "success" else { return }
                if let dataDict = json["data"].dictionary {
                    if let datas = dataDict["data"]?.arrayObject {
                        var titles = [HomeNewsTitle]()
                        titles.append(HomeNewsTitle.deserialize(from: "{\"category\": \"\", \"name\": \"推薦\"}")!)
                        titles += datas.flatMap({
                            HomeNewsTitle.deserialize(from: $0 as? NSDictionary)
                        })
                        completionHandler(titles)
                    }
                }
            }
        }
    }
}
........
  • 繼承協(xié)議(結(jié)構(gòu)體或類都可以)
struct NetworkTool: NetworkToolProtocol {}

然后丢烘,通過NetworkTool直接就可以調(diào)用NetworkToolProtocol的方法了柱宦。

  • 多多思考:
    至此,我們就可以通過面向協(xié)議的方式給類定制不同的功能播瞳,也就是模塊化掸刊。可以發(fā)現(xiàn)Swift的面向協(xié)議編程跟c++的多繼承很相似赢乓。

  • 思考二:此時的NetworkToolProtocol是可以被任意類繼承的忧侧,如果需要特定繼承呢?我們該怎么處理牌芋?
    約束:為了特定的繼承蚓炬,我們添加約束,比如只允許UserDiggViewController類繼承姜贡。

extension NetworkToolProtocol where Self : UserDiggViewController{}
2试吁、為什么要使用POP編程?

Swift已經(jīng)是一門面向?qū)ο蟮恼Z言楼咳,類已經(jīng)滿足我們的所有需求熄捍,功能也很強(qiáng)大,為什么還要使用POP呢母怜?
我們知道余耽,在Swift中,值類型優(yōu)先于類苹熏。然而碟贾,面向?qū)ο蟛荒芎芎玫嘏c結(jié)構(gòu)體和枚舉一起工作:因為結(jié)構(gòu)體和枚舉不能被繼承币喧。因此,作為面向?qū)ο蟮囊淮筇卣?------繼承袱耽,就不能應(yīng)用于值類型了杀餐。

3、面向協(xié)議編程(POP)的好處有什么呢朱巨?
  • 結(jié)構(gòu)體史翘、枚舉等值類型也可以使用。
  • 可以繼承多個協(xié)議冀续,彌補(bǔ)Swift中類單繼承的不足琼讽。
  • 增強(qiáng)代碼的可擴(kuò)展性,減少代碼的冗余洪唐。
  • 讓項目更加組件化钻蹬,代碼可讀性更高。
  • 讓功能代碼組成一個功能塊凭需,更便于單元測試问欠。
    使用示例:
    假設(shè)我們有一個ViewController,它繼承自UIViewController功炮,我們向其新添加一個方法 customMethod:
classViewController:UIViewController {
       func customMethod{
       }
}

此時溅潜,我們有另外個繼承自UITableViewController的OtherViewController,同樣也需要向其添加方法customMethod:

classViewController:UITableViewController {
       func customMethod{
       }
}

此時,問題就出現(xiàn)了薪伏,很難在不同繼承關(guān)系的類里共用代碼。此時的解決辦法就有一下幾種:

  • 復(fù)制粘貼方法粗仓,這種方法是最糟糕的解決方案嫁怀。
  • 創(chuàng)建一個基類添加上共享的代碼,或者在UIViewController上添加 extension借浊√潦纾可是隨著方法的增多,會讓基類由于職責(zé)不明蚂斤,什么方法都扔進(jìn)基類存捺,完全區(qū)分不了哪個類走了基類,很快變成了垃圾堆曙蒸。這樣會對項目造成混亂的影響捌治。
  • 依賴注入,通過外界傳入一個帶有 customMethod的對象纽窟,用新的類型來提供這個功能肖油。這是一個稍好的方式,但是引入額外的依賴關(guān)系臂港,也是我們不愿意看到森枪。
使用POP解決問題

a.定義一個含有customMethod的協(xié)議ex;

protocol ex {
func customMethod;
}

b.在extension中為customMethod添加實現(xiàn):

extension ex {
      func customMethod{
      //方法實現(xiàn)
      }
}

有了這個協(xié)議擴(kuò)展视搏,只要在ViewController和OtherViewController遵循ex協(xié)議,就可以直接使用customMethod方法了县袱。

4浑娜、協(xié)議繼承

協(xié)議可以從其它協(xié)議繼承,然后在它繼承的需求之上添加功能式散,因此可以提供更細(xì)粒度和更加靈活的設(shè)計筋遭。

5、協(xié)議的組合

類杂数、結(jié)構(gòu)體和枚舉可以符合多個協(xié)議宛畦,他們可以采用多個協(xié)議的默認(rèn)實現(xiàn)。是不是和多繼承很類似揍移?這種組合方式不僅比將所有需要的功能壓縮到一個基類中更靈活次和,而且也適用于值類型。

class FirstVC:ex1,ex2{
}

ex1,ex2,代表兩個不同的協(xié)議

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末那伐,一起剝皮案震驚了整個濱河市踏施,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌罕邀,老刑警劉巖畅形,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異诉探,居然都是意外死亡日熬,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門肾胯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來竖席,“玉大人,你說我怎么就攤上這事敬肚”霞觯” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵艳馒,是天一觀的道長憎亚。 經(jīng)常有香客問我,道長弄慰,這世上最難降的妖魔是什么第美? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮曹动,結(jié)果婚禮上斋日,老公的妹妹穿的比我還像新娘。我一直安慰自己墓陈,他們只是感情好恶守,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布第献。 她就那樣靜靜地躺著,像睡著了一般兔港。 火紅的嫁衣襯著肌膚如雪庸毫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天衫樊,我揣著相機(jī)與錄音飒赃,去河邊找鬼。 笑死科侈,一個胖子當(dāng)著我的面吹牛载佳,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播臀栈,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼蔫慧,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了权薯?” 一聲冷哼從身側(cè)響起姑躲,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎盟蚣,沒想到半個月后黍析,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡屎开,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年阐枣,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奄抽。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡侮繁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出如孝,到底是詐尸還是另有隱情,我是刑警寧澤娩贷,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布第晰,位于F島的核電站,受9級特大地震影響彬祖,放射性物質(zhì)發(fā)生泄漏茁瘦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一储笑、第九天 我趴在偏房一處隱蔽的房頂上張望甜熔。 院中可真熱鬧,春花似錦突倍、人聲如沸腔稀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽焊虏。三九已至淡喜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間诵闭,已是汗流浹背炼团。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓窟勃,卻偏偏與公主長得像赴涵,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子衔沼,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容