Bad programming practice 2

Functions

No naming conventions

就如同好的變數名稱一樣,一個好的函式名稱可以讓人一眼就看出來它的功能,而且更重要的是容易搞懂使用它的方法。這個在trace code的時候尤其重要,當你不是函式的原作者時,一個好的函式名稱能讓你事半功倍,在還沒開始之前就讓你有一個基本的概念,讓你知道你現在在往哪個方向前進。

Ambiguous function parameters

很多時候函式參數名稱讓你搞不清楚到底要傳什麼進去,到底是boolean value或是index?還是pointer?我看過最極端的例子是check_smart(a,b,c,d,e),我第一次看到時真的快吐血,多寫幾個字有這麼痛苦嗎?題外話:我認為Apple的objective-c在某種程度上嘗試解決這個問題,你想要用一個字當做變數?沒問題,可以,它用另外一個keyword來表示這個變數的意義。於是變數本身的名字和它所代表的意思已經不再綁在一起,所以一來你可以用一個字母來當參數,二來你不用再寫註解來說明變數的意義(反正你從來也沒寫過),三來在呼叫函式的時候,你不用再猜每個參數到底應該傳什麼,因為函式的名字已經包含了每個參數的意義。一舉數得,再方便不過。

The meaning of return value is ambiguous

有些函式的回傳值代表成功與否,成功是1,失敗是0,有些函式回傳值是錯誤碼,0是成功,非零則是失敗。如果你沒有辦法從函式名稱輕易看出區別的時候,那你就頭大了,除非這個函式有寫註解(通常是沒有),否則你唯一的方法就是跳進去trace裡面的程式,而且很有可能你不能只看return statement,因為你看不出那個return statement到底是在成功的時候執行還是失敗的時候執行。如果系統有定義boolean 型態可能還好一點,偏偏我們的系統都用unsigned int來代表boolean,這真的很麻煩,而且有些時候明明函式應該傳回true/false,卻有人利用unsigned int的特性來傳回某一個特定的數值去處理一個特殊狀況,這讓之後讀這段程式碼的工程師(就是我)真的很痛苦。更別提同樣是回傳boolean value,有些人用0代表成功,1表示失敗…

2,500+ lines in one function

這是真實案例,我們系統裡面某個ISR有2,517行,裡面有一個大的switch-case,包含了64個cases。用滑鼠中鍵來轉動畫面的話,大概要連續一分鐘才能看完 (前提是你的手還沒痠的話)。我猜全公司應該沒有人有全部看完過,也許連原作者也沒有吧?先不說64個cases的效率問題,這段程式寫出來擺明就不是要讓你看的,它就好像一個黑洞一樣,一進去就你就被吃掉了。

Several functions actually do the same job

也不是說這些函式全部都一模一樣,而是這些函式裡面總有30~50%的程式碼是重覆的,這就讓人看得很氣餒,覺得很煩燥。而且更重要的是,一但當你有這種心態的時候,你就不會發現在這些看似重覆的程式碼中,其實有一兩行是不一樣的,而偏偏整個函式最重要的地方就在這一兩行,然後你卻忽略了。這不是你的問題,而是原作者沒有好好的把函式的精髓表現出來,就如同前一點講的,「它不是寫給你看的」。我覺得所謂程式髒就在於這些地方,"Do not Repeat Yourself"絕對是走向乾淨程式碼的一個必要條件。

Use magic numbers a lot

函式裡面的數字通常很難表現出它背後所代表的意義,我覺得好的函式應該基本上看不到數字在裡面,除非是把變數設為0,否則最好是把數字定義成constant variable會比較增加可讀性。

Unclear function flow

很多時候一個檔案裡面有好幾個函式,然後你搞不清楚到底其中執行的順序是什麼。譬如說下面這些函式:

  1. execute_fwdownload()
  2. finish_fwdownload()
  3. checksum_firmware()
  4. save_firmware()
  5. download_start()
  6. fw_load_start()
  7. fw_load_complete()
  8. firmware_relocate()
  9. firmware_restart()

你大概可以知道某些函式是相對的,譬如說execute_fwdownload()和finish_fwdownload(),以及fw_load_start()和fw_load_complete()。但問題是execute_fwdonwload()和fw_load_start()之間的關係是什麼?你不看程式碼是不可能知道的。表面上看起來這裡的問題是函式命名不佳,但是實際的問題卻是缺乏結構性的設計。一個韌體下載的流程需要九個函式嗎?

No comment for the functions

有做過幾年工程師的人應該都知道,在業界實際的現象是通常沒有註解,就算有註解也和程式本身相差十萬八千里,不知道是哪一年哪一個好心的工程師加上去的。所以我覺得要求工程師寫註解有點不切實際,就像寫Design document一樣,不僅對工程師是額外的負擔而且品質沒辦法保證。我覺得比較可行的做法是儘量讓程式本身表達它的想法,讓程式本身成為註解。當然,這對工程師是一個很大的挑戰,畢竟這對編程的能力有一定的要求,但是我認為這是在現今普遍工程師時間不夠的情況下,能夠既保持系統可讀性又不耽誤進度的一個方法。

廣告

About Weicheng Chu

創業中,微碧愛普科技 (www.weibyapp.com) 已婚, 有一對雙胞胎兒子, 現居住在美國加州、台灣台中
本篇發表於 軟體工程 並標籤為 , , , , , 。將永久鏈結加入書籤。

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s