本文是我在團隊內部分享的ppt中摘出來的,所以可能節奏有點快。
用了Swift很久也沒有踏入POP的大門
並且充滿了誤解
- POP是Swift提出的一個全新理念
- POP就是狂用Protocol
- POP站在OOP的鄙視鏈上游
從電視劇的最後一集開始看,所以看不懂
之後改變了學習策略
- 【溯源】程式設計正規化發展歷史(電視劇的第一集)
- 【橫評】別的語言也有相似概念
- 【解構】分析Swift原始碼的設計
最初的程式設計正規化—結構化程式設計
最初的語言充滿了goto,goto是強大的,但是代價是巨大的
最初的程式設計正規化—結構化程式設計
直到有人提出結構化程式設計,來限制goto的權力
這幾個基本的控制流奠定了後世各種語言的基調但是結構化程式設計只解決了函式執行的複雜度,而資料還是亂的不行 這促使一個新的理念誕生了:Object-Oriented Programming
一個偉大思想的誕生
物件導向有三個特性解決過去混亂不堪的資料存放,也被稱為OOP三原則:
-
資料抽象 Abstraction
資料封裝提供了一個資訊隱藏的機制,讓一個類黑盒化,這種設計減少了人們理解一塊程式碼的難度。 -
繼承 Inheritance
繼承提供了共享程式碼的方式,不同於另一個世界線的原型鏈。 -
多型性 Polymorphism
多型提供了針對父類的演算法可以直接應用到子類上。
過去的資料存放雖然混亂,但是非常靈活,OOP則對這種能力加以限制(如同控制流對goto的限制)
簡單和靈活的辯證關係
成也繼承,敗也繼承
OOP在蓬勃發展之後,出現了兩個分支,單一繼承和多繼承。前者代表是JAVA,後者是C++。 多繼承首先暴露出很嚴重的問題:著名的The Diamond Problem
其次,多繼承會讓你的程式碼結構混亂不堪
單一繼承雖然避免了這個問題,但是他引起另一個問題:不夠用!從多個類共享程式碼是一個鋼需!
一般的單一繼承語言只好選擇組合(composition),但是組合引起不必要的層級和依賴。主要是用起來很麻煩。
所以Java在第8版的時候選擇一條少有人走的路,Mix-in正規化,Java裡叫介面擴充套件(interface extension)。
Mix-IN是何方神聖?
Mix-in也是比較古老的正規化,它是被近代的Ruby(1995)發揚光大。
Mix-in的解決思路是:既然多繼承不好,但是想共享程式碼,那麼就用重重約束允許某種受限的多繼承存在。
於是簡單和自由的取捨又出現了
Mix-in一般分為traits和介面擴充套件兩個流派,Ruby選擇是前者,而Java選擇加強他本來就有的pure interface,讓介面可以提供預設的方法實現,來完成和traits一樣的功能性。(這一點和Swift的發展路線是一致的)
實現Mix-in只需要這一個小小的改動,但是對整個軟體設計模式都產生了深遠影響。
Mix-IN加入後的新世界
因為Mix-in提供了功能實現,這些程式碼就可以當做一種元件,組合到任意的類裡,從而實現了類似多繼承的程式碼複用。
軟體架構不再是一塵不變的繼承+類組合,從此有了新的樣貌:
重點來了
Swift的POP就是Mix-in -> Java interface extension的延續,只不過改了名字叫protocol extension。
那充其量也就是Java的那種樣貌,怎麼能上升到Oriented的程度?
答案都在Swift的原始碼中。
Swift的野望
我們來看一下Swift對Int的實現
你沒看錯,除了Int本人是一個struct(甚至不是class)其它全都是Protocol! 誰還敢說不是Protocol-Oriented
歸根結底:Swift的POP到底是在說什麼?
Mix-in既然已經被證實是OOP的一個好的發展方向,Swift不但選擇引入Mix-in,並且把它提高到核心教義,並且用這個思想搭建起Swift語言本身。
可以說Swift不是Java那樣覺得Mix-in是OOP的補充,而是試圖證明Mix-in可以代替Class Inheritance成為優選的正規化。
連名字都改了不是嗎,OOP都不要了。
消除誤解
-
POP是Swift提出的一個全新理念
不是,他是古老的Mix-in,並且是被很多現代語言應用。 -
POP就是狂用Protocol
不是,重點在於繼承架構是否是圍繞Protocol設計的。 -
POP站在OOP的鄙視鏈上游
POP本身就是OOP的演化,只是在OOP(99%)的基礎上又邁進了一小步(1%)。
Swift走出的新路:POP之後的mix-in
通過Swift原始碼結構可以看出一個POP的軟體產生了大量的元件
具體型別(class/struct/enum)用來組合各種元件
甚至核心邏輯也是某一級的Protocol來組合,而具體型別只是一個能new出來的門面。
軟體設計的重心不再是建模物件,而是劃分能力。
POP符合程式語言的發展趨勢
父類和協議是OOP能提供的最高階抽象。他們是類的元型別。
POP提倡的就是在更高抽象層級上程式設計。
畢竟,越遠離goto,程式碼就越簡單。