GitHub最熱!碼代碼不得不知的全部定律法則

當談到開發問題時,人們總會談論各類定律。但對於大多數人來講,總有一些是你不瞭解的,這個問題就須要使用程序員最喜歡的方法解決了:最近 GitHub 上的一個「定律合集」項目忽然登上了趨勢榜第二位,Star 數上千,該項目對一些最多見的定律進行了歸納,詳情見下文。git

選自GitHub,做者:Dave Kerr,機器之心編譯。
程序員

你們都是資深程序員,之後就不要老唸叨「真香定律」了。github

本文包含對一些定律、原則和模式的解釋,但並不主張其中任何一項。是否要應用哪一個定律一直是一個爭論性問題,而且很大程度上取決於你在作哪方面的工做。編程

這些規則目錄以下:設計模式

定律安全

  • 阿姆達爾定律服務器

  • 布魯克斯法則網絡

  • 康威定律架構

  • 侯世達定律

  • 炒做週期 & 阿瑪拉定律

  • 海勒姆法則

  • 摩爾定律

  • 帕金森定律

  • Putt's Law

  • 複雜性守恆定律(泰斯勒定律)

  • 抽象漏洞定律

  • 帕金森瑣碎定律

  • Unix哲學

  • The Spotify Model

  • Wadler's Law

原則

  • 穩健性原則

  • SOLID

  • 單一功能原則

  • 開閉原則

  • 里氏替換原則

  • 接口隔離原則

  • 依賴反轉原則

對於以上如此多的定律和原則,咱們選取了其中一些定律和全部的原則進行編譯。如今,先簡單看一下定律吧↓↓

定律

阿姆達爾定律

維基百科:計算機科學界的經驗法則,因吉恩·阿姆達爾而得名。它表明了處理器並行運算以後效率提高的能力。阿姆達爾定律是固定負載(計算總量不變時)時的量化標準。

舉例說明,若是一個程序由兩部分(A和B)組成,A必須有單個處理器執行,B能夠並行執行,那麼在執行該程序的系統中增長多個處理器帶來的好處是有限的。它可能會大大提高B的速度,但A的速度會保持不變。以下如所示:

從圖中能夠看出,一個程序若是隻有50%的部分可並行處理,那它使用10個以上處理單元時,處理速度將不會有很大的提高。而一個程序若是有95%的部分可並行處理,即便使用的處理單元超過1000個,其處理速度也會顯著提升。

侯世達定律

維基百科:作事所花費的時間老是比你預期的要長,即便你的預期中考慮了侯世達定律。

當你估計作一件事要花費多長時間時,可能會想到這必定律。軟件開發中的老生常談是,咱們每每很難估計交付某個東西所須要的準確時間。

炒做週期 & 阿瑪拉定律

維基百科:咱們老是高估一項技術的短時間效益,而低估其長期效果。

此定律被描述爲鼓勵人們思考科技所能帶來的長期影響的言論。同時,阿瑪拉定律也被人們稱爲是對「炒做週期」(技術成熟度曲線)最形象的說明。以下圖所示:

簡言之,這一週期代表,新技術及其潛在影響一般會引發一陣興奮。而後不少團隊快速投入該技術,而後有時會對結果感到失望。這多是由於技術還不夠成熟,也多是由於現實應用尚未徹底實現。

通過一段時間後,技術的能力增長,使用技術的實際機會也增長,置身其中的團隊最終開始受益。

海勒姆法則

網絡定義:當一個 API 有足夠多的用戶時,你在約定中承諾什麼都無所謂,全部在你係統裏面被觀察到的行爲都會被一些用戶直接依賴。

海勒姆法則指出,當你的API有很是多的用戶時,API中的全部行爲最終都會被某我的所依賴。舉個簡單的例子:非功能性元素,如API的響應時間。稍微複雜一點的例子:依賴對錯誤消息應用正則表達式來肯定API錯誤類型的用戶。

摩爾定律

該定律認爲,集成電路中的晶體管數量大約每兩年翻一番。

該定律一般用來表示半導體和芯片技術發展的絕對速度。從上世紀70年代到90年代末,摩爾的預測一直很是精準。但近年來,該趨勢已經發生了細微的變化,部分緣由在於組件小型化程度受到的物理限制。然而,並行化的發展以及半導體技術和量子計算領域潛在的革命性變化,可能意味着摩爾定律在將來幾十年仍將適用。

複雜性守恆定律(泰斯勒定律)

該定律認爲每一個系統內都有必定的複雜性不可減小。

系統中的某些複雜性是「不經意的」。多是由結構不良、錯誤或只是建模不良形成的結果。這些不經意形成的複雜性是能夠減小(或消除)的。可是,有些複雜性是「固有的」,是由亟待解決問題的內在複雜性形成的。而這種複雜性能夠移動,但沒法消除。

這個定律有趣的一點在於,即便簡化整個系統,也沒法下降內在的複雜性。這種方法只不過是將複雜性轉移到了用戶一方,而後用戶必須以更復雜的方式行事。

帕金森瑣碎定律

該定律認爲,大型組織會花費大量時間和精力來討論可有可無的雜事,可是真正重大的決議反而能夠輕鬆過關。

這是由於,在討論很是專業並且金額龐大的事情時,通常人因爲缺少專業知識,不敢隨便發言,以避免失言,貽笑大方,所以多半都會確定(或逃避)該重大方案,而提些與主題無關的雞毛蒜皮小事。相對的,對於簡單的瑣碎小事,因爲日常你們都會接觸到並且有至關的認識,反而意見特別多,帕金森稱此現象爲瑣碎定律。

Unix 哲學

Unix哲學認爲,軟件組件應該很小,並且應該把注意力放在具體的事件上。將小的、簡單的、定義良好的單元組合在一塊兒,而不是使用大的、複雜的、多用途程序,這樣可使構建系統變得更加容易。

像「微服務架構」這樣的現代實踐就應用了這種哲學。在該架構中,服務很小,且集中作某件事,使得複雜的行爲由簡單的構件組成。

Wadler 定律

該定律認爲:在任何語言設計中,討論這個列表中某個特性所花費的總時間與它位置的冪成正比。

1.語義

2.語法

3.詞彙語法

4.註釋的詞彙語法

(簡言之,若是在語義上花1小時來討論,那將在註釋語法上花8小時)。

與帕金森瑣碎定律類似,Wadler 定律認爲,當設計一種語言時,花在語言結構上的時間與這些特徵的重要性相比很不成比例。

原則

在這篇文章中,做者表示原則是指導程序猿開發新應用的一些方針。在碼代碼的過程當中,咱們常常會遇到各類困難,固然也有各類約定俗成的規則。例如最簡單的命名法,有的默認爲使用下劃線、使用小駝峯或大駝峯式的命名,只有瞭解這些規則,編寫的代碼纔是優美的。

穩健性原則

在維基百科中,穩健性原則(Robustness Principle)描述爲:「寫代碼要保守,要能接受其它方面的各類信息」。

該原則一般應用於服務器應用的開發,它表示發送的內容應該儘量少且符合要求。但若是能夠處理不符合要求的輸入,那麼你的目標應該但願容許各類非一致性的輸入。

該原則的目標是構建一個穩健的系統,對於輸入端,只要對方的意圖仍能夠理解,那麼咱們就應該須要處理非標準格式的輸入。然而,接受格式錯誤的輸入有潛在的安全影響,特別是當這種輸入的處理方式尚未通過良好的測試。

SOLID

該原則是一個縮寫,即:

  • S:單一功能原則

  • O:開閉原則

  • L:里氏替換原則

  • I:接口隔離原則

  • D:依賴反轉原則

如上所示, SOLID 指代了面向對象編程和麪向對象設計的五個基本原則。當這些原則被一塊兒應用時,它們使得程序員能開發更容易進行軟件維護和擴展的系統。SOLID常應用在測試的驅動開發上,而且是敏捷開發以及自適應軟件開發的基本原則的重要組成部分。下面讓咱們看看這5個基本原則都是什麼吧。

單一功能原則

在維基百科的描述中,單一功能原則(Single responsibility principle)規定每一個類都應該有一個單一的功能,而且該功能應該由這個類徹底封裝起來。全部它的(這個類的)服務都應該嚴密的和該功能平行(功能平行,意味着沒有依賴)。

這一原則代表模塊或類應該只完成一件事。這意味着對程序特性的單個小修正,應該只須要在一個組件中進行更改。例如,更改驗證密碼的方式應該只須要更改程序特定的某個模塊。

保持一個類專一於單一功能點,這樣作的重要緣由是它會使得類更加穩健。若是咱們知道正在修改的組件只有一個功能,那麼測試會變得更簡單,新的修改也就好處理了。例如上面,修改密碼驗證應該隻影響與密碼驗證相關的特性,若是咱們要對具備多功能的模塊進行修改,這樣進行推斷就要複雜多了。

開閉原則

在面向對象的編程中,開閉原則規定:軟件中的對象(類、模塊、函數等等)對於擴展應該是開放的,可是對已存行爲的修改是封閉的。這意味着,一個實體須要容許在不改變源代碼的前提下變動它的行爲。

該特性在產品化的環境中特別有價值,由於在產品化中改變源代碼須要代碼審查,例如單元測試等方法確保產品使用的質量。遵循這種原則的代碼在擴展時並不發生改變,所以無需上述過程。

舉個栗子,假設某個模塊可以將 Markdown 文本轉換爲HTML。若是模塊能夠擴展新的特性,即能處理新提出的Markdown 特性而不修改模塊內部,那麼這就表示它對擴展是開放的。

這一原則與面向對象的編程特別相關,咱們能夠設計易於擴展的對象,但也要避免設計不穩定的對象,由於它們的現有行爲可能會以意想不到的方式發生改變。

里氏替換原則

里氏替換原則(Liskov Substitution principle)是對子類型的特別定義。里氏替換原則的內容能夠描述爲: 派生類(子類)對象能夠在程序中代替其基類(父類)對象。也就是說,若是一個模塊依賴於某個類,那麼該模塊就須要能使用該類的派生類,且不會發生系統錯誤。

舉個栗子,若是咱們有一種方法,它能夠從表徵文件的結構中讀取XML文本。若是該方法的基類是「file」,那麼它能調用從「file」派生的任意類。

這一原則對於面向對象的編程很是重要,咱們必須仔細建模類的層次結構,以免讓系統用戶感到困惑。

接口隔離原則

接口隔離原則(interface-segregation principles)指明用戶(client)應該不依賴於它不使用的方法。接口隔離原則拆分龐大臃腫的接口成爲更小的和更具體的接口,這樣用戶將會只須要知道他們感興趣的方法。這種縮小的接口也被稱爲角色接口(role interfaces)。接口隔離原則的目的是系統解開耦合,從而容易重構、更改和從新部署。

舉個栗子,假設咱們有一種可以從表徵文件的結構中讀取XML文檔的方法。這種方法只須要讀取字節以及在文件中前移或後移便可。若是該方法由於文件結構的一種非相關性特徵改變而須要進行更新(如用於表徵文件安全的權限模型的更新),則該原則無效。文件最好實現‘seekable-stream’接口並讓XML reader使用。

該原則與面向對象編程具備特殊的相關性,其中接口、層次和抽象類型用於最小化不一樣組件之間的耦合。鴨子類型(duck typing)經過消除顯式接口來執行該原則。

依賴反轉原則

在傳統的應用架構中,低層次的組件設計用到高層次的組件中,這一點提供了逐步的構建一個複雜系統的可能。在這種結構下,高層次的組件直接依賴於低層次的組件去實現一些任務。這種對於低層次組件的依賴限制了高層次組件被重用的可行性。

依賴反轉原則的目的是把高層次組件從對低層次組件的依賴中解耦出來,這樣使得重用不一樣層級的組件實現變得可能。把高層組件和低層組件劃分到不一樣的包/庫,該方式也促進了這種解耦。因爲低層組件是對高層組件接口的具體實現,所以低層組件包的編譯是依賴於高層組件的,這顛倒了傳統的依賴關係。衆多的設計模式,好比插件、服務定位器或者依賴反轉,則被用來在運行時把指定的低層組件實現提供給高層組件。

具體而言,依賴反轉原則規定:

  • 高層次的模塊不該該依賴於低層次的模塊,二者都應該依賴於抽象接口。

  • 抽象接口不該該依賴於具體實現。而具體實現則應該依賴於抽象接口。

舉個栗子,若是咱們有一個從網站讀取元數據的程序,且主組件包含下載網站內容的組件和讀取元數據的組件。若是咱們考慮依賴反轉原則,那麼主組件只能依賴於某些抽象組件,其中某個抽象組件只能獲取比特數據、另外一個只能從比特流中讀取元數據。主組件並不知道任何關於TCP/IP、HTTP或HTML等協議或格式的相關信息。

這一原則是比較複雜的,由於它彷佛反轉了系統的依賴性關係。在實踐中,該原則意味着獨立的編排模塊必須確保使用了正確的抽象類型實現。例如在上面的例子中,元數據讀取模塊仍是須要一些抽象類型的實現,即HTTP文件下載器和HTML元標籤讀取器。

相關文章
相關標籤/搜索