面向協議編程的一些思考

本文是我在團隊內部分享的ppt中摘出來的,因此可能節奏有點快。算法

用了Swift好久也沒有踏入POP的大門

而且充滿了誤解編程

  • POP是Swift提出的一個全新理念
  • POP就是狂用Protocol
  • POP站在OOP的鄙視鏈上游

從電視劇的最後一集開始看,因此看不懂設計模式

以後改變了學習策略

  • 【溯源】編程範式發展歷史(電視劇的第一集)
  • 【橫評】別的語言也有類似概念
  • 【解構】分析Swift源碼的設計

最初的編程範式—結構化編程

最初的語言充滿了goto,goto是強大的,可是代價是巨大的 架構

via http://ziogeek.com/wp-content/uploads/2013/07/spaghetti.jpg

最初的編程範式—結構化編程

直到有人提出結構化編程,來限制goto的權力 編程語言

這幾個基本的控制流奠基了後世各類語言的基調

可是結構化編程只解決了函數執行的複雜度,而數據仍是亂的不行 這促使一個新的理念誕生了:Object-Oriented Programming 函數

via http://www.kamyacademy.com/wp-content/uploads/2014/01/object-orientated-programming-langs.png

一個偉大思想的誕生

面向對象有三個特性解決過去混亂不堪的數據存放,也被稱爲OOP三原則:學習

  • 數據抽象 Abstraction
    數據封裝提供了一個信息隱藏的機制,讓一個類黑盒化,這種設計減小了人們理解一塊代碼的難度。spa

  • 繼承 Inheritance
    繼承提供了共享代碼的方式,不一樣於另外一個世界線的原型鏈。 設計

    JS原型鏈

  • 多態性 Polymorphism
    多態提供了針對父類的算法能夠直接應用到子類上。3d

過去的數據存放雖然混亂,可是很是靈活,OOP則對這種能力加以限制(如同控制流對goto的限制)

簡單和靈活的辯證關係

via https://www.success.com/sites/default/files/styles/article_main/public/main/articles/Find%20Balance.jpg?itok=pQrQxtxY

成也繼承,敗也繼承

OOP在蓬勃發展以後,出現了兩個分支,單一繼承和多繼承。前者表明是JAVA,後者是C++。 多繼承首先暴露出很嚴重的問題:著名的The Diamond Problem

via https://en.wikipedia.org/wiki/Multiple_inheritance

其次,多繼承會讓你的代碼結構混亂不堪

via http://public.beuth-hochschule.de/~solymosi/veroeff/objektdiagramme/bilder/Multip2.jpg

單一繼承雖然避免了這個問題,可是他引發另外一個問題:不夠用!從多個類共享代碼是一個鋼需!

通常的單一繼承語言只好選擇組合(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提供了功能實現,這些代碼就能夠當作一種組件,組合到任意的類裏,從而實現了相似多繼承的代碼複用。

軟件架構再也不是一塵不變的繼承+類組合,今後有了新的樣貌:

單一繼承樹+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,代碼就越簡單。

相關文章
相關標籤/搜索