友快網

導航選單

【第183期】一個程式設計師的自白:我為什麼寫出一個無比優雅的程式碼?!

點選載入圖片

我是一個著迷於產品和運營的技術人,樂於跨界的終身學習者。歡迎關注我喲~

每週五12點 按時送達~

我的第「183」篇原創敬上

大家好,我是Z哥。

我相信每一位

程式設計師

最怕遇到程式碼質量堪憂的專案,畢竟增加一個同樣的功能,在一個程式碼整潔、清晰的專案裡與在一個程式碼混亂不堪的專案裡,效率和質量上的差距達到一個數量級一點也不奇怪。

但是殘酷的現實是,“垃圾專案”到處存在,哪怕是大廠裡也不例外。畢竟,沒有人天生就能寫出無比優雅的程式碼,都是透過寫“垃圾程式碼”一步一步成長起來的,唯一的區別可能就是成長的速度不同罷了。

一個專案如果運氣好,未來成為受重視的專案,那麼它還有機會擺脫不少的“垃圾程式碼”,但是如果沒那麼好運,那就苦了後來人了。

所以,如果你是一位新人程式設計師,那麼我得提醒你,一定要有一個合理的預期,這個合理的預期就是——與垃圾程式碼長期為伴。因此,如果你以後因為遇到“垃圾程式碼”而破口大罵,這是不講“碼德”的。什麼?那麼索性跳槽?你怎麼能確保下一個接手的專案會更好?

在Z哥看來,一個專案走向“垃圾”、人見人棄的地步,原因只有一個,程式碼垃圾,而什麼樣的程式碼才算垃圾程式碼?這就多了,我與你分享一些常見的。

01元件顆粒度過大

現在三層架構基本已經成為一個基礎共識了,只要不是太古老的專案,不太會存在UI、業務邏輯、資料操作寫在一起的情況。(雖然架構設計方面的後起之秀很多,但是三層架構因為更容易理解,所以市場佔有率依舊最高)

但是三層架構的每一層又該如何進一步細分,如何建模?還沒有能夠成為共識的統一標準或者最佳實踐出來。

所以,很多專案在經歷了一年以上的業務發展和變更後,業務邏輯層往往率先淪陷,開始出現大物件,成為開發效率的瓶頸。

近幾年的火熱的領域驅動設計其實已經開始深入到每一層的內部該如何劃分上了。但是離達到共識還有很長的路要走。

02API數量氾濫

有一些經驗的程式設計師們會用一招來讓自己在垃圾程式碼中游走自如。這招就是儘量透過“增加”的方式實現功能而不是“修改”歷史程式碼。

這種方式的確能避開很多“屎坑”,但是從長期來看,這大機率是在創造新的“屎坑”。

某些核心class裡幾百個function,成千上萬行的程式碼就是這麼來的。

03低內聚、高耦合

「高內聚、低耦合」是軟體開發領域的一條黃金法則,相信每一位程式設計師都知道。但是現實是,很多專案都存在低內聚、高耦合的問題。

出現這個問題倒也不是說是由於大量的重複程式碼導致,而是過度的追求消除重複程式碼。盲目的追求減少重複程式碼,自然會導致程式碼被過度拆分,原本一個完整的業務處理清清楚楚,硬生生被拆分到多個function裡去。

複用當然是好的,但應該有個前提條件:不增加系統複雜度的情況下的複用。如果不這樣做,損害了穩定性,增加了複雜性,還會造成程式碼可讀性降低。

04業務邏輯和程式處理邏輯糾纏

Z哥認為,程式碼的作用其實就分為兩種,業務邏輯和程式處理邏輯。前者體現的是這個軟體的現實價值,後者則是讓軟體能在計算機上run起來必不可少的部分。

程式處理邏輯主要就是各種資料的存取、dao操作、序列化/反序列化、快取操作,以及異常處理、引數和返回值準備等等。

如果程式的處理邏輯與業務邏輯混在一起,就好比芝士拌飯,都黏在一起,隨便改一小點功能就扯出一大段程式碼要看。

更加可怕的是,如果裡面還充斥著大量Magic Number,比如if (errCode == 50001) 。那你得忍住不要罵人。

05又長又寬的if else

這點其實長期以來就是一直被人詬病的陋習。但是這又幾乎是每一門程式語言都有的語法,那麼問題到底在哪裡?

因為不管是if else也好,還是switch case也好,其實是一種硬編碼的方式。這就會導致它不容易被修改。

想象一個場景:某個列舉增加了一個新的值,這個時候你需要將原先判斷這個列舉的所有if else都檢查一遍,以確保新增的業務能正確執行。真正做過這件事的人相信有過深刻地感受,如果這個列舉被用到幾十上百的地方,檢查一遍外加弄懂上下文,估計至少半天時間就沒了,而且很有可能最終還是漏改或者改錯什麼。

以上就是一些常見的垃圾程式碼的樣子。那麼,在你的工作中如果遇到充滿垃圾程式碼的垃圾專案該怎麼辦呢?從流派上說,主要有三大流派,激進派、保守派、重頭再來派。

保守派的做法,主要是從區域性修改問題程式碼入手。比如前面提到的這些“垃圾”程式碼,常見的處理思路是以下這些。

01業務層禁止層內依賴

你可以留意觀察一下,業務層內的內部相互依賴,是導致程式碼高耦合低內聚的主要推手。因為這會導致一個業務方法體內部經常容易囊括一些不在當前業務邏輯內的分支邏輯,使得每個方法的耦合逐漸提高。

所以,禁止層內依賴對降低耦合有立竿見影的效果,這也是領域驅動設計提倡專門拉出一個Application Layer來協調各個Domain之間的互動的目的。

02將大函式拆小

讓程式碼恢復健康,最難啃的骨頭就是那些動輒幾百上千行的函式。保守派雖然避免了大量應用新框架進行替換所帶來的工作量。但是這個最難啃的骨頭是避不開的坎,否則所謂的程式碼重構只是隔靴搔癢而已,並沒有多大效果。

03減少程式碼

減少程式碼最高效的方式是呼叫新的系統api或者使用新的框架或者工具。他們可以大批次的代替原先冗餘的「程式處理邏輯」。只是對保守派來說,他們會更謹慎地使用新的框架。畢竟,運用一個新框架可是一個不小的手術。

激進派與保守派最大的區別在於,他們更傾向於使用新的框架、工具甚至是新的技術棧、程式語言來解決問題。不過在我看來,這些新東西,可能在短期的確能解決眼前的問題,但是這些問題到底是新技術解決的?還是因為使用新技術而大量重寫“新鮮”的程式碼解決的?值得打上一個問號。

最後的重頭再來派很有意思。他們認為老專案已經沒救了,必須重做才行,這是比激進派更激進的一個流派。

可是我見過好多重頭再來派的人員,重頭再來做出的專案,在其他人眼裡可能並沒有比之前好多少,甚至在過了一段時間之後,發現重新陷入了之前的困境之中。

因為盲目樂觀是我們人性的弱點。這就像創業者總覺得自己是九死一生中唯一生的那個,買彩票的人總覺得自己是那個千萬分之一的幸運兒一樣。

這三個流派,並沒有絕對的好壞之分,不同的流派都有不同的適用場景,區別就在於「時間、成本、質量」這三個要素上的取捨不同。所以,我們在選擇方案的時候可以根據這三個要素的具體情況來判斷。

因為Z哥認為一個專案的核心要素就是這三者,並且這三者無法兼得,最多隻能取其二,類似於分散式系統領域的CAP定理。

Z哥有幸分別參與和主導過這三個流派的工作,以我的經驗來看,我認為這三個流派分別適用的專案情況如下:

保守派。時間快,成本低,對質量僅有最基本的要求。

激進派。有較高的質量要求,滿足時間較寬裕或者接受成本大幅增加其中的一點。

推倒

重來

派。時間和成本完全給質量讓步,追求可見範圍內的最好。

其實這麼一分析你也能發現,總是推到重來是不現實的,時間和成本這種屬於資源,資源總是有限的。所以,大多數情況下,保守派的選擇才是最常見的。因此我們更應該思考的是如何透過保守改造最大化提高專案的質量,讓他擺脫“垃圾”的標籤。這需要我們沉下心來才能完成,不要老想著推翻重做。

好了,總結一下。

這篇呢,Z哥和你分享了我對如何應對“垃圾專案”的看法。

首先和你分析了5個常見的使得專案逐漸變得垃圾的陋習。

元件顆粒度過大

API數量氾濫

低內聚高耦合

業務邏輯和程式處理邏輯糾纏

又長又寬的if else

然後分享了三個常見的保守派做法:

業務層禁止層內依賴

將大函式拆小

減少程式碼

最後分享了應對“垃圾專案”時的三大流派,分別是:

保守派

激進派

推倒重來派

從時間、成本、質量三個維度的權衡來看。保守派才是主流,所以不要動不動就想著推倒重來,收起浮躁的心,沉下心來。

好了,希望對你有所啟發。

推薦閱讀:

不做思想的巨人

幫助閱讀原始碼的8個技巧

也可以「關注」我,帶你以技術思維看世界~

內容包括:架構設計丨分散式系統丨產品丨運營丨個人深度思考。

上一篇:【燒友評測】ipad mini 5:小巧的機身,強勁的晶片,優秀的螢幕素質,優
下一篇:【手機圈】買二手iphone如何避坑?點選載入圖片這些小技巧你都知道嗎?