Swift(學習): 面向協議編程

面向協議編程

  • 面向協議編程(Protocol Oriented Programming,簡稱POP) 
  1. 是Swift的一種編程範式, Apple於2015年WWDC提出
  2. 在Swift的標準庫中,能見到大量POP的影子
  • 同時,Swift也是一門面向對象的編程語言(Object Oriented Programming,簡稱OOP) 
  •  在Swift開發中,OOP和POP是相輔相成的,任何一方並不能取代另一方
  • POP能彌補OOP一些設計上的不足

回顧OOP

  • OOP的三大特性:封裝、繼承、多態
  • 繼承的經典使用場合
  • 當多個類(比如A、B、C類)具有很多共性時,可以將這些共性抽取到一個父類中(比如D類),最後A、B、C類繼承D類


OOP的不足

  • 但有些問題,使用OOP並不能很好解決,比如 
  • 如何將BVC、DVC 的公共方法run 抽取出來?

  • 基於OOP想到的一些解決方案?

1.  將run方法放到另一個對象A中,然後BVC、DVC擁有對象A屬性 

缺點:多了一些額外的依賴關係

2.  將run方法增加到UIViewController分類中
缺點:UIViewController會越來越臃腫,而且會影響它的其他所有子類

3.  將run方法抽取到新的父類,採用多繼承?(C++支持多繼承)
缺點:會增加程序設計複雜度,產生菱形繼承等問題,需要開發者額外解決


POP的解決方案

  • 更復雜的情況:把B2和C1的共有方法抽取到protocol

 


POP的注意點

  • 優先考慮創建協議,而不是父類(基類)

   因爲類會優先想到繼承,會影響到面向協議編程

  • 優先考慮值類型(struct、enum),而不是引用類型(class)

 

  •  巧用協議的擴展功能

     比如可以將協議裏的方法實現寫在擴展裏

  • 不要爲了面向協議而使用協議

利用協議實現前綴效果


Base:類


Base:協議

 


利用協議實現類型判斷

func isArray(_ value: Any) -> Bool {return value is [Any]}
func isArray1(_ value: Any) -> Bool {return value is Array<Any>}

print(isArray([1, 2])) //true
print(isArray(["1", 2])) //true
print(isArray(NSArray())) //true
print(isArray(NSMutableArray())) //true

print(isArray1([1, 2])) //true
print(isArray1(["1", 2])) //true
print(isArray1(NSArray())) //true
print(isArray1(NSMutableArray())) //true

protocol ArrayType { }

extension Array: ArrayType {}
extension NSArray: ArrayType{}

func isArray2(_ type: Any.Type) -> Bool {
    return type is ArrayType.Type
}
print(isArray2([Int].self)) //true
print(isArray2([Any].self)) //true
print(isArray2(NSArray.self)) //true
print(isArray2(NSMutableArray.self)) //true

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章