個人if else代碼純淨無暇,一個字也不能簡化

機器之心報道,參與:劉曉坤、王淑婷、李澤南。前端

「我曾接手過一個代碼,裏面是幾十個 if else 模塊……」對於程序員們來講,遇到這樣的事情應該是苦不堪言的——不少人認爲這種寫法很是難看、分支衆多、容易出 bug。最近,網友們在容器管理平臺 Kubernetes 的 GitHub 上發現了這樣一段代碼,其中的 1700 行 if else 語句卻讓人歎爲觀止。git

爲了防止「頭鐵」羣衆真的去重構它,在這段代碼的開頭,有這樣一段註釋:程序員


不要嘗試簡化此代碼。github


請看着它起飛。編程


這個控制器是故意以很是詳細的方式編寫的。你會注意到:後端


1. 每一個『if』語句都有一個匹配的『else』(除了客戶端 API 調用的簡單錯誤檢查)函數


2. 在這裏咱們要明確地解釋一下學習


咱們把這種代碼叫作『航天飛機風格』。航天飛機風格是爲了確保每一個分支和條件都獲得考慮——就像在 NASA 編寫航天飛機的航天器應用程序代碼同樣。測試


最初,這個控制器的工做被分紅了三個控制器來作。該控制器是爲簡化 PV 子系統付出巨大努力的結果。在這種努力中,很明顯咱們須要確保在代碼中處理和計算每一個條件,即便它致使了無操做代碼分支。優化


所以,控制器代碼可能看起來過於冗長,有太多註釋和「分叉」。可是,這裏記錄了大量的業務知識和內容,以確保將來的維護者可以正確地推理綁定行爲的複雜性。所以,對此文件的更改應保持航天飛機風格。

該文件的 GitHub 地址:github.com/kubernetes/…

1700 行的 if 嵌套語句。

做爲流行的開源系統,Kubernetes 常被用於自動容器化應用程序的部署和管理。其開發者稱,Kubernetes 擁有 15 年承擔 Google 生產工做負載的經驗。對於人工智能領域的開發者來講,Kubernetes 能夠幫助咱們部署深度學習模型(參見:如何使用 Kubernetes 輕鬆部署深度學習模型)。

航天飛機的風格

據說它是美國航天局 NASA 的代碼風格?在 Hackernews 上,衆多網友們在通讀全文代碼後給出了一致好評。

@Klathmon 表示:

我愛死這個了!這簡直就是軟件開發裏的「爵士樂」。它打破了全部的固有「規則」,但目的明確,比按照「規則」來的結果要好得多。

乍一看,你會以爲這個文件太大了,裏面充斥着許多分支和嵌套 if 語句,還有不少「無心義的註釋」,僅描述周圍一行或幾行代碼是作什麼的。註釋裏還有不少 logic,與實際代碼相比,這些 logic 很快就會過期或者出錯。

但同時,這樣作使得維護和管理代碼變得簡單多了,由於你不用把 logic 拆分紅幾十甚至上百個文件。它包含了大量對這個文件須要進行的固有複雜工做,而它的註釋作得又好又多,作任何改變均可以輕易讓註釋一塊兒更新。

@munchbunny 說:

不能更贊成了。我平常要處理的代碼不是這個級別,但也有低級別的特色,一樣也比典型的後端代碼更接近 metal,被許多的前端和後端代碼調用。若是有「甚至更後端代碼」的東西,這就是個不錯的例子。若是你忽略了一個細微的差異,一羣憤怒的開發人員會在部署代碼時衝到你辦公桌前,而若是你沒有快速修復它,就會出現一羣憤怒的顧客。

對於任務關鍵型代碼內部循環中的代碼來講,主要的時間成本並非寫代碼或者理解代碼,而是根據所服務場景的細微差異進行優化,檢查更改代碼帶來的直接影響,而後檢查更改的二階和三階影響。

當你的代碼很是細化,以致於你作的每一個改變都有三階影響時,帶有精心註釋的代碼會更容易維護。由於假如你拼湊了十個不一樣的文件,須要花費精力弄清正確的路徑,就更有可能忽略其中的細微差異。

關於註釋

不少網友對於帶大量註釋的代碼表示頗有用、不反感,而且那些不帶註釋的代碼會帶來很大的麻煩。

@EB66 說:

我徹底贊成。對於那些不可避免很複雜的代碼,我也喜歡這種風格。

我很是喜歡簡潔且語句/命名是表達性的代碼,但有時候註釋是必要的,以便清楚地闡明邏輯或使用案例。表達性代碼能直接傳達的含義有限。精心設計的註釋能夠大大地減小其餘開發人員在不熟悉的代碼基礎上所耗費的時間。

關鍵是要更新註釋。沒有比不許確的註釋更噁心的事了。檢查代碼時必定要檢查修改過的代碼行的註釋。

@ascar 說:

解釋使用案例或目的的過期註釋仍是比沒有註釋強。它能給你提供背景信息,好比代碼的演變及其目的。

只讀註釋可能比讀沒有註釋的代碼更糟糕,因此一些開發人員反感過期的註釋,所以就有了通常化(過於簡略)的註釋。

註釋是關於代碼的附加信息,沒有事實來源,因此,要同時閱讀代碼和註釋。

@nickharr 說:

我有 25 年以上用多種語言編寫、查看、註釋和檢查代碼的經驗,因此我會說這的確是一個好東西——無論編程的「風格」(或者廣義上來講的語言)如何。

好的代碼註釋能夠對生產力產生巨大的影響——不管是對我的、團隊仍是企業來講都是如此。它有助於存儲知識(當前和以前的團隊/我的之間容易丟失的信息)。

我我的花了太多時間對那些沒有註釋的代碼進行逆向工程。有時候,經驗豐富的程序員或開發人員會走捷徑:壓縮程序和函數,這些程序和函數是基於他們明確瞭解的語言和/或領域,但沒有對它們進行註解……

在基本層面上,註釋應該告知、教育、概述和幫助他人理解咱們寫代碼時創造的有時很複雜的路徑和函數。

有些人認爲好的代碼不須要註釋,某種程度上這是對的,但這一點並不適用於每一個代碼庫。有些代碼很複雜、笨拙,就像意大利麪,有時甚至難以理解。

我一直努力教經驗較少的開發人員以帶點幽默(可能的話)的方式做出高效的好註釋——讓咱們可以快速理解代碼,欣賞前人所作的努力,並笑對複雜的挑戰。

我我的並不真正關心代碼和註釋的比率。有時,代碼註釋可能比代碼自己更有價值。而有時,它們只是幫助你完成工做;只要快速、高效、沒毛病,就是不錯的代碼。

文件大小

@Klathmon 說:

我從事前端網頁應用開發,其中最複雜的問題在於如何實現代碼庫的快速迭代,大部分狀況下都不是實際的業務問題。但儘管「deep functionality and small interfaces」聽起來很不錯,大多數狀況下,導出的僅有少許函數的大型文件是不容易維護的。將全部代碼放到同一個文件中,須要你在作出任何修改以前確保透徹地理解它們。

@taneq 說:

他們是有目的地這樣作的,爲了確保開發人員在修改以前能理解整個文件,由於其功能很是關鍵,很容易被混淆。此外,將一個邏輯嚴密的文件分割成小型文件(而不是改寫成更小的邏輯模塊)只會致使沒必要要的文件管理問題。

新手的膜拜

@jml7c5 說:

做爲一個初學程序員,我很是震驚這居然不是編程的標準慣例。通常的源文件應該提供語境、主題背景、解釋概念的參考資料/博客/書籍指南、關於代碼如何匹配程序總體的信息,以及(最重要的)文件中體現的思考過程(即爲何選擇這種作法而不是其它,面臨的挑戰,權衡等等)。

我仍是想不通,每一位程序員都須要從零開始學習使用一個代碼庫。除非肯花費數小時來作測試,想改善一個 non-trivial 的程序是不可能的。致開源開發者:若是你想要讓人們對項目作出貢獻,這些類型的註釋是很基本的,更不要說它們能幫助節省很是多的時間。

@qlk1123 說:

「做爲一個初學程序員,我很是震驚這居然不是編程的標準慣例。」我贊成這一點,若是這能成爲社區標準,固然會有不少人受益。可是,你不認爲一個好的社區文化可讓人們爲此保持良好的習慣嗎?

個人平常工做是 Linux 內核開發人員。我發現源代碼僅僅是「What」部分,註釋中應該聲明「How/Why」部分。而且若是這些還不能使我搞明白源代碼,我會直接電郵做者問更深層次的「Why」部分。大多數狀況下信息都是足夠的。

模仿需謹慎

Kubernetes 以外,最近另外一個由於代碼而被熱議的程序可能就是在 Steam 上火起來的獨立國產遊戲《太吾繪卷》了。據好奇的程序員介紹,其早期版本中內含數千個 if 語句。因爲遊戲主創是中文系出身,隨後又投身建築行業,半路出家寫遊戲代碼——最後竟然玩起來沒有什麼大問題,代碼的「糟糕」樣式成爲了一個梗,爲遊戲的流行起到了助推做用。

這些著名的案例雖然能夠運行,但沒有強大的邏輯(運氣)是玩不轉的。科班出身的程序員們通常就不要模仿了。

相關文章
相關標籤/搜索