Swift 中面向協(xié)議編程的應(yīng)用划址,與面向?qū)ο蟛煌木幊棠J街АT?Swift 這個現(xiàn)代化的編程語言中和泌,感受面向協(xié)議帶來的變革!
面向?qū)ο缶幊讨两褚呀?jīng)使用了數(shù)十年了滥沫,并且成為了構(gòu)建大型軟件約定俗成的標(biāo)準(zhǔn)侣集。作為iOS編程的中心思想,遵循面向?qū)ο笠?guī)范來編寫一個 iOS 的應(yīng)用幾乎不可能實現(xiàn)兰绣。雖然面向?qū)ο笥泻芏鄡?yōu)點比如封裝性,訪問控制和抽象性编振,但是它也自帶有固有的缺點缀辩。
1:大多數(shù)類的情況下臭埋,當(dāng)一個單繼承的類需要更多不同類中的函數(shù)功能時,你會傾向于使用多繼承來實現(xiàn)臀玄。 但是大部分的編程語言不支持這一特性瓢阴,而且會導(dǎo)致類的繼承關(guān)系變得復(fù)雜。
2:在多線程環(huán)境下健无,如果所有對象在函數(shù)中都是通過引用來傳遞會導(dǎo)致意想不到的問題荣恐。
3:因為類與類之間的高耦合性,為一個單獨的類寫測試單元會很困難累贤。
Swift 嘗試引入一種叫做面向協(xié)議的編程新規(guī)范來解決傳統(tǒng)的面向?qū)ο缶幊讨泄逃械膯栴}叠穆。WWDC2015 演講做了一個令人驚嘆的關(guān)于面向協(xié)議編程的介紹。Swift 在最初的時候是包含值類型的概念臼膏。結(jié)構(gòu)體和枚舉都是 Swift 中的一等公民硼被,還擁有很多像 propertites, methods 和 extensions 等在大多數(shù)語言只有類才有的特點。雖然在Swift中值類型不支持繼承渗磅,但是通過遵循協(xié)議的方式一樣能夠享受到面向協(xié)議的好處嚷硫。
Ray Wunderlich 的面向協(xié)議編程的教程展示了它的能力。
Introducing Protocol-Oriented Programming in Swift 2
現(xiàn)在我將向你展示面向協(xié)議編程是如何點亮我的人生的始鱼。我的應(yīng)用程序遵循經(jīng)典的左側(cè)菜單導(dǎo)航模式(附帶一些選項)仔掸。這個應(yīng)用大概有十個不同的 view controller,它們都是繼承自一個擁有基礎(chǔ)函數(shù)和各個界面所需樣式的基類 view controller医清。
和我的應(yīng)用相似的左側(cè)菜單的應(yīng)用例子
這個應(yīng)用依賴于 Webscokets 來與服務(wù)器交互嘉汰。服務(wù)器可以隨時發(fā)送事件,而應(yīng)用根據(jù)用戶所在的界面來進(jìn)行相應(yīng)的事件響應(yīng)状勤。舉個事件例子的話鞋怀,比如登出事件,當(dāng)用戶收到了服務(wù)器關(guān)于這個狀態(tài)的事件時持搜,應(yīng)用需要登出并顯示登錄界面密似。
在我腦中的第一想法是把登出事件寫在基礎(chǔ)的 view controller 里面,當(dāng)事件發(fā)生的時候葫盼,在需要的 view controller 進(jìn)行調(diào)用残腌。
這一步的問題就是并不是每個 view controller 都必須實現(xiàn)這個登出的功能,但是它還是都會繼承這個登出的函數(shù)贫导。此外不同的 view controller 需要響應(yīng)不同的事件抛猫,所以在基礎(chǔ) view controller 中包含所有的函數(shù)并沒有什么意義。
幸運地是面向協(xié)議編程拯救了我孩灯,我聲明一個 Logoutable 的協(xié)議闺金,那些需要登出功能的 view controller 遵循這個 Logoutable 的協(xié)議就可以了。
這一個進(jìn)步帶來的問題是我必須在每個需要遵循這個協(xié)議的 view controller 中重復(fù)這個登出函數(shù)的實現(xiàn)峰档。
這正是面向協(xié)議編程在 Swift 中的閃光點败匹,因為它給我們提供了協(xié)議拓展功能寨昙,可以在一個協(xié)議中定義一個默認(rèn)的函數(shù)的行為。所以我所需要做的僅僅是在 Logoutable 的協(xié)議中寫一個帶有默認(rèn)登出行為的實現(xiàn)的拓展掀亩,這樣這個函數(shù)對那些遵循這個協(xié)議的 view controller 的來說就是可選的舔哪。
面向協(xié)議編程完全就像魔法一樣,不定義任何復(fù)雜的繼承就夠就實現(xiàn)這些功能〔酃鳎現(xiàn)在我就能為不同的事件定義不同的協(xié)議并且各自 view controller 就能夠遵循它所需要的協(xié)議捉蚤。
面向協(xié)議編程是真正地點亮了我的人生,現(xiàn)在每當(dāng)我需要使用繼承或者其他面向?qū)ο蟮脑韥順?gòu)建我的代碼時炼七,我會想這能否通過使用面向協(xié)議編程的方法來更好的完成這項工作缆巧。我不是說它是完美的解決方案但是它仍然值得一試。