烂代码长什么样?
最近看別人寫的代碼看得頭疼,寫這篇不僅是總結同時也告誡自己不要寫出爛代碼禍害別人。看不懂別人的代碼是什么感覺?就好像走進一片森林里迷了路,這時候你是不是想把寫代碼的人抓過來罵一頓?下面就總結幾條最讓人受不了的。
?
標志位以及全局變量太多
標志位看似用起來很方便,是為了表達一種狀態,然而一旦起了就要去維護,什么時候清零?什么時候置 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),而不是冷門的讓別人看不懂。
如果你覺得本篇不錯,請幫忙轉起來吧!
作者簡介:綠羅裙,智能家居嵌入式軟件工程師,一個程序媛媽媽。
本文為作者投稿,版權歸作者所有。
總結
- 上一篇: Redis 内存压缩实战
- 下一篇: 最全面的JVM G1学习笔记