前言
OC無(wú)法做到面向協(xié)議開(kāi)發(fā),而Swift可以,因?yàn)镾wift可以做到協(xié)議方法的具體實(shí)現(xiàn),而OC不行
面向?qū)ο箝_(kāi)發(fā)OOP
OOP 的優(yōu)點(diǎn)包括可重用性,繼承,可維護(hù)性,對(duì)復(fù)雜性的隱藏(封裝),抽象性,多態(tài)性,對(duì)一個(gè)類(lèi)的屬性和方法的訪問(wèn)權(quán)限控制。傳統(tǒng)的面向?qū)ο箝_(kāi)發(fā)思維方式是將類(lèi)中實(shí)現(xiàn)的相似方法抽取出來(lái),接著放入一個(gè)Base類(lèi),然后繼承于Base類(lèi)后各個(gè)類(lèi)即可找擁有相同的方法,不用再一個(gè)個(gè)手動(dòng)實(shí)現(xiàn)。
比如:一個(gè)Person類(lèi),一個(gè)Dog類(lèi),它們都擁有方法eat,那么就可以新建一個(gè)Animal類(lèi),將eat方法抽取出來(lái)放入其中,然后將Person類(lèi)和Dog類(lèi)都繼承于Animal。
但是,如果現(xiàn)在又有一個(gè)Robot類(lèi),也需要擁有eat方法,而此時(shí)也將其繼承于Animal的話(huà)顯然是不合理的,于是我們就需要轉(zhuǎn)換思維,面向協(xié)議開(kāi)發(fā)~
面向協(xié)議開(kāi)發(fā)POP
所謂面向協(xié)議編程,就是使用protocol聲明方法,然后使用extension提供默認(rèn)的實(shí)現(xiàn),只要需要使用到該方法的類(lèi)遵循該protocol,就可以直接使用該extension的實(shí)現(xiàn)。
和OOP主要的一點(diǎn)不同在于:類(lèi)只能繼承自其它一個(gè)類(lèi),但協(xié)議可以繼承自多個(gè)協(xié)議。
protocol animal {
var food: String {get}
func eat()
}
extension animal {
func eat() {
print("food name is \(food)")
}
}
struct Cat: animal {
var food: String = "mouse"
}
struct Dog:animal {
var food: String = "cat"
}
let cat = Cat()
let dog = Dog()
cat.eat()
dog.eat()
log:
food name is mouse
food name is cat
代碼復(fù)用
- 繼承:會(huì)帶來(lái)耦合。
繼承的代價(jià):這并不是一個(gè)新穎的話(huà)題,自面向?qū)ο缶幊陶Q生之日起就飽受爭(zhēng)議,我們經(jīng)常要忍受著愈加繁雜和龐大的繼承體系來(lái)獲得代碼的可重用性,而且隨著繼承層次的增加,代碼的復(fù)雜性會(huì)加速增長(zhǎng),隨之而來(lái)的bug也會(huì)越來(lái)越難以發(fā)現(xiàn)。這時(shí)我們可能需要依靠設(shè)計(jì)模式來(lái)找回我們的思路,然而大多數(shù)設(shè)計(jì)模式只能幫助你理順你的代碼結(jié)構(gòu),卻在同時(shí)更加加深了你的代碼的復(fù)雜度。
category/extension:會(huì)污染所有的類(lèi)
面向協(xié)議編程:
protocol+extension最大程度地減少了耦合
面向協(xié)議編程的好處
面向協(xié)議編程的好處在于,通過(guò)protocol+extension實(shí)現(xiàn)一個(gè)功能,能夠定義所需要的充分必要條件,不多也不少。這樣就最大程度減少了耦合。使用者可以像搭積木一樣隨意組合這些協(xié)議,寫(xiě)一個(gè)class或struct來(lái)完成復(fù)雜的功能。實(shí)際上,Swift的標(biāo)準(zhǔn)庫(kù)幾乎是everything is starting out as a protocol。
為什么說(shuō)Swift是面向協(xié)議編程的語(yǔ)言?
Apple 聲稱(chēng)”從核心上說(shuō),Swift 是面向協(xié)議的”。協(xié)議構(gòu)成了 Swift 標(biāo)準(zhǔn)庫(kù) 的基礎(chǔ),Swift 中的協(xié)議有其他語(yǔ)言都不支持的特點(diǎn):協(xié)議擴(kuò)展.
協(xié)議可以被擴(kuò)展,來(lái)給遵循該協(xié)議的類(lèi)型提供方法、初始化方法、下標(biāo)、計(jì)算屬性的具體實(shí)現(xiàn)。這就可以允許協(xié)議自身定義一些行為,而不是由各個(gè)類(lèi)型自己去實(shí)現(xiàn),或是由一個(gè)全局方法來(lái)實(shí)現(xiàn)。
通過(guò)擴(kuò)展,我們可以為協(xié)議所要求的任何方法和計(jì)算屬性提供一個(gè)默認(rèn)的實(shí)現(xiàn)。如果一個(gè)遵循該協(xié)議的類(lèi)型為某個(gè)方法或?qū)傩蕴峁┝似渥约旱膶?shí)現(xiàn),那么該實(shí)現(xiàn)將會(huì)替代協(xié)議擴(kuò)展中的實(shí)現(xiàn)。
Swift里更推薦使用值類(lèi)型變量(struct)而不是引用類(lèi)型(class)的變量,struct沒(méi)有繼承的功能,這是因?yàn)閟wift在本質(zhì)上來(lái)說(shuō)是面向協(xié)議(Protocol Oriented)的語(yǔ)言,struct沒(méi)有也不需要繼承的功能,為了實(shí)現(xiàn)某個(gè)功能,struct去服從并實(shí)現(xiàn)某個(gè)協(xié)議就即可,從一個(gè)較高的層次來(lái)看,struct+protocol是構(gòu)成swift面向協(xié)議語(yǔ)言的兩個(gè)基石。
總結(jié)
Swift是一門(mén)支持多編程范式的語(yǔ)言,既支持面向?qū)ο缶幊蹋仓С置嫦騾f(xié)議編程,同時(shí)還支持函數(shù)式編程。在項(xiàng)目開(kāi)發(fā)過(guò)程中,控制器和視圖部分由于使用系統(tǒng)框架,應(yīng)更多采用面向?qū)ο缶幊痰姆绞?;而模型或業(yè)務(wù)邏輯等自定義類(lèi)型部分,則應(yīng)優(yōu)先考慮面向協(xié)議編程。