iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 4
1
自我挑戰組

軟體工程漫談系列 第 5

『這位工程師,你在公三小』-- 論命名的重要性

大學時期,我們花了很多時間學習資料結構,讓資料有適當的儲存方式;我們也學演算法,讓系統運算快而正確;我們學網路、學組合語言、學計算機結構、...,但是,出了社會開始工程師生涯,卻發現什麼快速排序法、雜湊圖的,人家都已經做好library讓我們去使用了,而我們花最多的時間,其實是在『讀前人的code』、『修別人的bug』。

你知道的,不要說是讀別人的code了,光是自己的程式碼,過了兩個月再回來看,也都看起來像是別人寫的。每次接到任務,光是要看懂而忍住不罵髒話,就已經很辛苦了。『為什麼你們這些人寫程式要這麼隨便?』恐怕是大多數工程師在看別人程式碼時的共同心聲了。

為了公司整體,與為了未來的自己,何不一開始就寫出較易了解的程式?要知道,寫出機器能懂的程式並不難,只要compile能過他就懂了,而寫出人能懂的程式才是真功夫。『無瑕的程式碼』是我認為一個好的工程師應該具備的能力,然而叢書系列這麼多本,原則範例這麼多,我們要從哪裡開始呢?千里之行始於足下,我們從命名開始吧。


變數的命名

最基本的就是變數的命名了。這點,應該比較容易遵守。簡單來說,變數一定要讓人看了就知道是要做啥的。

int myInt
double money
double money_1

這樣的命名是否讓你頭痛?因為從名稱無法馬上看出用途,必須得再往下看邏輯才知道,這樣就拖慢了閱讀速度,就是不好的命名,就更別說上面的money和money_1這種容易使人混淆的命名了。改成這樣如何:

int userId
double balanceBefore
double balanceAfter

看完變數定義,還沒看後面程式碼,大概就能猜到接下來應該是一段針對某個userId進行balance調整的程式。要不要往下繼續閱讀,就可以很快判斷出來,是不是很省時?


函式(method/function)的命名

韓式的命名也很重要,一般來說閱讀程式時,大多以top-down的方式來閱讀,所以,一旦函式命名得好,讀者即使不點進去看,也會知道這一段在做啥,如果是不重要的,他就可以放膽跳過,就算是重要的,他也不用花很多時間點開來一行一行閱讀,可以馬上抓住整短的邏輯脈絡,進而,你知道的,減少因誤會原意而生的錯誤。

更有甚者

public User getInfo()
public User getAdvancedInfo()
public User getFurtherUserInfo()
public User getMoreMemberInformation()
public User retrieveMember()

如果不點開來一個一個看,鬼才知道這些函式有什麼不一樣!不要造成後備或未來的自己的困擾,這種讓人混淆的命名,還是少取為妙,阿彌陀佛!


類別命名

類別命名也是很重要的。一般來說,我們會希望類別的命名和函式與變數一樣,一看就懂。然而,類別的命名又更難了,為什麼?因為系統的功能是隨著公司的發展而累積的。一個類別誕生後,經過時代的演進,很容易就會被加入原本不屬於他應做的是,或是被移除了一些功能,使得這個類別的命名再也不合時宜,譬如:

public class UserManager {
  public User getUser(String name);
  //public void addUser(User user);
  public void addUser_new(User user, Mode mode);
  public List<Item> checkPurchasedItems();
  public Map<Integer, Item> findRecommendedItems()
}

你可以想像,UserManager創始之初,應該只有getUser與addUser兩個函式,而後來應該是因為一些需求變更,加了新的user建立模式,但是舊的函式又不敢貿然刪除,於是就先把它給註解掉。後來又因為別的需求,加了取得推薦商品與已購買商品等功能。

如此一來,UserManager這個名字已經不合時宜了,要的話,也應該改成UserAndItemManager才對。

但是,事情可沒這麼簡單。這樣的命名雖然合時宜了,但是卻大大地違反單一職責原則。如果要追求真正的Clean Code,變成一個優秀的工程師,我們應該要把Item相關功能從UserManager身上移除,譬如,另外各自創立Invoice以及Recommender的類別才對。

喔,順帶一提,上面回傳Map<Integer, Item>的方式,也是違背Clean Code原則的,這會增加一些未來被誤用的風險,不過,那就又是另外的故事了...

最後,我們知道人生不能重來,但是git可以。於是,只要你有用不到的類別、變數、或是函式,都應該要大膽地刪除才對,以免影響閱讀。如果哪天真的有重啟功能的需求,大不了回舊版來找便是。


以上只是Clean Code眾多原則中最基礎的命名原則,也是命名原則中最基本的第一步。但是,不踏出第一步,怎麼到的了偉大的航道?注意:一旦命名容易使人混淆,閱讀後續的程式碼就容易誤會,邏輯就容易被改錯。這是我們所不樂見的。

可惜的是,怎麼寫出好懂易讀的程式,學校卻很少著墨。這真的有賴大家平常的注意,以及經驗的累積了。


上一篇
什麼是hotfix? Kuma老師的英語教學時間
下一篇
『用註解補足程式碼易讀性?』 -- 論註解的是與非
系列文
軟體工程漫談7

1 則留言

0
小魚
iT邦大師 1 級 ‧ 2017-12-09 20:49:13

我覺得註解很重要,
我的程式裡面註解占了不小的篇幅,
想要找那一段程式碼直接搜尋註解就會找到了。
/images/emoticon/emoticon39.gif

Kuma iT邦新手 5 級 ‧ 2017-12-09 21:56:52 檢舉

這個點真的很棒
事實上關於註解在程式中扮演的腳色真的很重要,到我認為幾乎跟程式本身一樣重要,幾乎啦!他也帶來很多方便性。

然而,跟程式一樣要寫是一回事,要維護又是一回事了。

習慣,才是真正的問題。

我要留言

立即登入留言