每日最新頭條.有趣資訊

爛代碼長什麽樣?

最近看別人寫的代碼看得頭疼,寫這篇不僅是總結同時也告誡自己不要寫出爛代碼禍害別人。看不懂別人的代碼是什麽感覺?就好像走進一片森林裡迷了路,這時候你是不是想把寫代碼的人抓過來罵一頓?下面就總結幾條最讓人受不了的。

標誌位以及全局變量太多

標誌位看似用起來很方便,是為了表達一種狀態,然而一旦起了就要去維護,什麽時候清零?什麽時候置 1?什麽時候初始化?當所表達的這件事情不簡單,比如跟另一件事情有牽扯,標誌位就不好用了,會有很多地方需要把他清零或置 1,一旦有個地方忘了程式就會出錯。標誌位一兩個還好,多了別人看得頭昏,能避免就避免,實在避免不了怎麽辦?等一下再寫,過一會就發現其實不用也可以。

全局變量(這裡指的是 int 型或 char 型等基本類型的變量)跟標誌位同理,太多只會引起頭昏,用之前應該明確這個變量的作用範圍,如果作用範圍只是在一個函數裡面,那麽就沒必要起在外面,直接在本函數起一個“static”類型的就可以了,也許有時候起的時候並沒有發現這個變量可以在函數裡寫成 static,代碼寫完後多看看就發現了。同理作用在本檔案的那就在本檔案裡定義成 static。

比單個檔案中全局變量更可怕的是一個變量跨越幾個檔案使用,一不注意看花眼,心累不心累?如果一個變量確實會在幾個模塊裡被讀和寫怎麽辦?可以在一個模塊定義成 static,然後通過讀和寫的接口函數來實現讀寫就好了。

在筆者看來,全局變量這種東西能不用就不用,一般涉及相同業務的變量一起組成一個結構體在結構體裡面定義,單獨起一個全局的結構體就夠了,而不是這裡一個那裡一個單獨的變量散落在檔案的各個地方。

比如當某件事情發生時 A 模塊會去寫某個變量,讓 B 模塊來讀,此時定一個標誌位以及變量,當 B 模塊發現標誌位置 1 了就去讀變量,這種做法就不太好。AB 模塊完全可以通過消息隊列來通信,A 模塊只需要把變量值通過發特定消息帶給 B 模塊就好了,這樣就實現了 B 模塊在事件發生時得到了這個變量。

邏輯不夠簡單

邏輯複雜一方面可能是產品的功能本來就設計的複雜;一方面可能是寫程式的時候思路不清晰,實現方法不夠簡潔,代碼一團糟自己把自己作死的。如果這兩方面都佔了,那差不多到了要吐血的邊緣了。

如果功能邏輯複雜該怎麽辦?代碼該怎麽寫就應該好好規劃,先想清楚別急著寫。

拿我們的產品舉個例子,智能家庭網關子設備綁定入網流程就比較複雜,首先手機 App 在局域網內搜索子設備,網關收到搜索消息,去開啟 ZigBee 子設備入網流程,入網成功後子設備開始登陸到伺服器流程,這個過程中手機持續發搜索消息,網關持續回復搜索消息告知子設備基本資訊以及連網處於哪一階段(比如與網關連接中、登陸伺服器中)直到子設備登陸伺服器成功,獲得了登陸 ID 號,手機向伺服器申請綁定該子設備,整個流程結束。

體現到代碼上,整個過程中涉及到三個線程,局域網線程、廣域網線程、ZigBee 線程。其中,ZigBee 線程需要同時與局域網、廣域網線程通信,廣域網線程可能需要與局域網線程通信,這關係簡直太複雜了。你無法想象原來代碼靠一堆的 flag 和變量就把這功能做完了,你需要捋好多遍才搞清楚,那些名字相似的變量們都是些什麽作用。

具體怎麽做暫且不談,反正讓我做是不會做成這樣的,可以利用作業系統的消息隊列、回調函數、信號量等等讓線程間通信變得簡單些,作業系統就是為了讓我們更簡潔地編碼啊!

函數設計不合理

一個函數功能不單一

這是很容易會犯的錯誤,有時候某個函數被設計成完成一種功能,但隨著產品功能迭代更新,發現程式執行到這有了另外一種情況這個函數處理不了了,於是不得不在原來函數裡面又補上一段。

這樣就造成了這個函數有好幾個功能:正常情況時就是原來功能,新的情況時,又是另外一種功能。從函數名看是只有前面這種功能,裡面卻藏著另一種功能,反正看著有些不爽,如果有時間來改一下,也許可以設計成兩個函數,正常情況執行函數 A,新的情況執行函數 B。

功能切分不合理

到底什麽功能可以包裝成一個函數?會被反覆用到的功能,或實現起來代碼比較多,放在程式裡太長,細節又可以屏蔽的功能。不要幾句代碼就能實現的功能還要寫一個函數,也不要很多不相乾的東西全湊在一個函數裡,函數又臭又長讓人失去了耐心,然後又在某個旮旯裡藏著關鍵性邏輯。

嵌套調用太多層

假如 A 函數調用 B 函數,B 函數裡面又調用 C 函數,C 函數裡面…….暈不暈?

可讀性差

魔鬼數字

比如陣列的第 5 個元素減 7,為什麽是 5?為什麽是 7?讓人摸不著頭腦,可以把 5 和 7 定義成巨集,從巨集的名字體現出其意義;

沒有注釋

這不用多說了吧,關鍵函數、關鍵邏輯都應該加上適當注釋讓後來者好維護;

命名風格不統一

無論是變量、函數還是檔案名,都應該能望名知義並保持一樣的規則,比如一個模塊提供給其他模塊的接口函數命名都保持”模塊名 _ 功能”這樣子,忽然來了個不按這種規則命名的函數,那就比較影響閱讀,處女座會受不了的;另外英文的簡寫盡量用常見的(比如 count 一般縮寫成 cnt),而不是冷門的讓別人看不懂。

如果你覺得本篇不錯,請幫忙轉起來吧!

作者簡介:綠羅裙,智能家居嵌入式軟體工程師,一個程式媛媽媽。

本文為作者投稿,版權歸作者所有。

【完】

獲得更多的PTT最新消息
按讚加入粉絲團