Swift面向協議編程
來源:互聯網
上載者:User
一、使用類的好處 1.封裝性 2.抽象性 3.採用命名空間來避免衝突 4.表意性極強的語句 5.可拓展性
在Swift中,前三點使用結構體和枚舉就也完全可以實現。
二、在以往的物件導向編程中,只有類才能提供的 1.類的繼承層次體系 2.類由於方法變數可重載所具有的可定製和重用性
在Swift中,可定製性用結構體也可實現。
三、類的使用代價 1.參考型別帶來的隱式共用(implicit sharing) 為此,你有時需要不斷的調用copy來給每個可變數(mutable)自己的值,而且會降低系統的運行效率,可能會導致死結,使代碼變得更加複雜,還會導致各種Bug。
以往collectionType的絕對分享性會導致的各種問題在Swift中不會出現,因為Swift中collectionType是實值型別而不是參考型別,它們不分享。
2.你需要繼承父類的一切 它太過臃腫,所有可能相關的都被一股腦丟了進去,而且你在一開始就必須決定好你的父類,而不是後期根據需求選擇。
如果父類有儲存類型的變數,你別無選擇必須全部接受它們。而且要對它們進行初始化,還要注意不破壞父類的常量。
你需要選擇是否和如何以可行的方式對父類方法進行重載。
3.類的抽象性導致類型之間的關係資訊丟失(Lost Type Relationship) 你在什麼資訊都不瞭解的時候,還必須在最初的父類中一定會被重載方法裡面放一些代碼。
你需要用as! 對抽象的類型進行進一步的明確。
四、我們需要一種更好的抽象機制 1.支援實值型別(包括類) 2.支援靜態類型關係(static type relationship)和動態派發 4.支援可回溯的模型設計 5.不存資料 6.沒有初始化負擔 7.明確接收者要實現什麼(與類方法重載的模糊性形成對比)
五、Swift是一門面向協議(Protocol-Oriented)的程式設計語言
六、一切從協議開始 1.避免了書寫不必要的方法實現代碼 2.不再需要重載 3.在協議方法定義中中使用self來解決類型關係丟失(Lost Type Relationship)
protocol
Ordered {
func
precedes(other:
Self
) ->
Bool
}
4.將異質聲明轉化為同質
當Ordered為Class時:
func
binarySearch(sortedKeys: [
Ordered
], forKey k:
Ordered
) ->
Int
{
var
lo =
0
var
hi = sortedKeys.
count
while
hi > lo {
let
mid = lo + (hi - lo) /
2
if
sortedKeys[mid].precedes(k) {
lo = mid +
1
}
else
{
hi = mid
}
}
return
lo
}
當Ordered為Protocol時:
func
binarySearch<T: Ordered>(sortedKeys: [
T
], forKey k:
T
) ->
Int
{
var
lo =
0
var
hi = sortedKeys.
count
while
hi > lo {
let
mid = lo + (hi - lo) /
2
if
sortedKeys[mid].
precedes
(k) {
lo = mid +
1
}
else
{
hi = mid
}
}
return
lo
}
七、若你在Protocol 中使用Self ,Protocol 與Class 的差異會變的更大 1.採用泛型而不是類型 2.同質化而不是異質化的思考方式 3.類型執行個體之間的交流不再意味著兩個類型之間的交流 4.採用效率更高的靜態派發方式
八、協議拓展 文法見四天前的 Swift 2.0文法更新(二)
Renderer 是Protocol,TestRenderer 是滿足Renderer 的結構體。 第一張圖對Renderer進行了拓展,添加了兩個方法,一個是原protocol中要求的CircleAt 和新添加的RectangleAt。 第二張圖對結構體TestRenderer進行了拓展,添加了兩個相同的方法。
若以圖二所示的方式定義r, CircleAt會調用extension TextRenderer中的CircleAt,而RectangleAt會調用 extension Render中的RectangleAt。
在該種定義方式中,優先順序:在原協議中被未要求的協議拓展方法 > 類型拓展方法 > 在原協議中被要求的協議拓展方法。
九、More Protocol Extension Tricks 因水平有限暫不翻譯
十、什麼時候我們該用類 1.對執行個體的比較和複製沒有意義的時候(例如:Window) 2.執行個體的生命週期取決於外部影響的時候(例如:暫時性的檔案) 3.執行個體只能夠被寫入來影響外部狀態(例如:CGContext) 4.而且不要對抗物件導向的系統API
十一、總結 Protocol > Superclasses Extension protocol 很神奇
英文原版視頻請見WWDC Session 408 https://developer.apple.com/videos/wwdc/2015/?id=408