在過去的七年半中,我在Ronimo遊戲公司指導過十幾個程式設計師實習生,審閱了數百份履歷。我發現他們中的大多數都需要學習一件事情。你可能以為這是某一技術、演算法、數學,或其它形式的某方面知識。當然,他們的確需要彌補這些知識,但在我看來,這些都不是最重要的。他們要去學習的最重要的一件事是:自律。這種自律體現在:編寫盡可能清晰的程式碼;重構程式碼以消除因後續開發中的變化所造成的混亂;移除從未用過的程式碼並且添加註解。
我指導實習生的大部分時間不是在高級技術或引擎細節的解釋上,而是讓他們寫出更好的程式碼。我總是會問實習申請者:要成為一個優秀的程式設計師,你們認為哪些是重要的?他們的回答通常是:程式碼要清晰,易懂,方便維護。這當然是我想聽到的,但是很少有年輕的程式設計師能從一而終地去實踐。
做到這些需要自律,因為這意味著程式碼不能停留在「實現了功能」。假設所有的變數都被隨意地命名,程式碼依然能夠完美運行,但是閱讀性很差。從短期來看,從「功能型程式碼」到「清晰型程式碼」的回報很少:程式碼原本就可以運行,對其清理之後程式碼仍然可以運行。這就是為什麼需要自律來完成這一步,這也是為什麼參加實習會很有幫助:一個好的導師會非常注重程式碼的品質(儘管不同的人對「好的程式碼」有不同的定義),從而要求實習生進一步改進完善,走到下一個階段。
下面給幾個例子,這些是我在新手程式設計師所寫的程式碼裡常看到的問題:
名不副實的函數/變數//類別
這些函數、變數、類別所做的事情並不是他們名字所暗示的那樣,這些名字具有欺騙性。顯然名字應該反映真實的內容,但讓我吃驚的是,名不副實這種情況常常出現。 舉個例子,我最近偶然看到以前一個實習生寫的兩個類別:EditorGUI 和 EditorObjectCreatorGUI,這程式碼本來就是用來處理編輯器裡的介面。令我吃驚的是,創建新物件的按鈕的程式碼放在了 EditorGUI 裡面,而EditorObjectCreatorGUI則是處理不同物件間的操作,這都跟名字所暗示的完全相反!儘管程式碼比較簡單,但我花了好大一會兒才弄清楚,因為我基於類別名稱做出了完全錯誤的假設。這個案例的解決辦法很簡單:重新命名為 EditorObjectCreatorGUI和 EditorObjectNavigationGUI,只要做一小步就可以大幅提升閱讀性。
命名不準確這種情況我看到很多。之所以頻繁發生,是由於程式碼不斷演變。最初選擇那個命名時可能是正確的,但一到程式碼完成之後,命名可能就變得不準確甚至錯誤的了。這個陷阱提醒我們應該始終把命名記在心上,在你添加一段程式碼的時候就要弄清楚,這與函數或類別的名稱是否相稱。 混淆不清的類
另一個問題是混淆不清的類,即一個類做了很多不相關的事情。當你長時間專注於同一塊程式碼時,就可能這個問題。新功能用最簡單的方法實現,到了某種程度,類別就會變得臃腫,做了很多不相關的事情。有時候類變得臃腫不在於程式碼規模的大小:一個類別可能只有幾百行,但它卻包含了不屬於本類功能的程式碼。 舉個例子,如果一個GUI類別需要「分析哪些紋理可供使用」(設想有個按鈕用於選擇紋理),如果GUI類是唯一一個需要這種分析結果的類,那麼在GUI類別裡實作它是很合理的。但是,這時一個完全不相關的gameplay類別也需要這種分析結果的訊息,因此你將GUI類別傳遞給gameplay類別來查詢紋理資訊。這時候GUI類別就多出一種東西了:它是GUI類,同時也是TextureAnalyser類別。這個案例的解決方案很簡單:從TextureAnalyser類別分割出一個獨立的類別,這個類別可同時被GUI類別和gameplay類別使用。 避免這種問題的最佳方法是在每次寫程式碼前三思:我在這裡添加的功能跟類別的名稱符合嗎?如果不符合,那麼就要對類別重命名,或是分割成獨立的類別,或是把這段程式碼放到其他的類別中。
如果想不出來一個跟類別非常匹配的名字,這通常是代碼異味(Bad Smell)。如果找不到合適的名字來描述這個類,可能因為它所做的事情太混雜了。這時可以將它分割成幾個部分,並且每個部分用一個恰當的名字來描述。
體積龐大的類
這問題跟上面所說的類很相似:隨著混淆不清時間的推移,越來越多的程式碼被加到一個類別裡,使得其變得臃腫。在這種情況下儘管放在一個類別是很合理的,但是類別的體積變得很大。超大的類別處理起來是很麻煩的,當很多程式碼對同一個私有成員變數進行操作時,bug就很容易出現,而且人也很容易忽略很多細節。
分割一個超大的類別是件相當無聊的工作。當程式碼高度交錯時,這也具有很大的挑戰性。分隔程式碼需要高度的自律,因為這只是對現有的程式碼進行增加或修改而保持原有的功能不變。
Ronimo公司有一個規定,保持類別的程式碼在500行以下,函數的程式碼在50行以下。有時候這是不可行也不合理的,但是通常來說,不管哪一個類別或函數超出了這個規定,我們都會尋找辦法將其重構或分割成更小的,更易於管理的片段。 (這讓我很好奇:你覺得這個限制應該是多少行?可以在評論中留言。)
程式碼註解 程式碼註解
實習申請人給我們寄過來的樣本程式碼幾乎都有一些被註解的程式碼區塊,但並沒有說明為什麼會做這個註解。是程式碼存在錯誤需要修改嗎?還是程式碼過舊需要更新?註解掉的程式碼為什麼會在這裡?當我們問起申請人時,他們對這些被註解的程式碼也顯得很疑惑,但是奇怪的是,總是會有一些原因不明的被註解的程式碼。 程式碼重複
另一個我常看到的問題是有類似功能的程式碼重複出現。
舉個例子,從紋理名字也許可以看出這東西的用途,如TreeBackground.dds。為了知道這個紋理是否可以用於一棵樹,我們檢查以Tree開頭的檔案名稱。也許當使用SDK後我們能很快找到,使用beginsWith(”Tree”)就行了。這個程式碼很短,如果需要用到它,直接貼到那裡就可以了。這就是程式碼重複,而且人人都知道程式碼重複是應該避免的,如果重複的程式碼很短,那麼最吸引人的做法是直接複製貼上。在這兒的問題很明顯:以後如果要檢查這個紋理是否適用於別的東西,我們就要進行散彈式修正,一個地方一個地方修正了。
通常比較好的做法是,如果程式碼功能特殊,不要去複製,而是把它放到一個函數裡。儘管程式碼很短很短,而且呼叫一個函數比貼上需要寫更多的程式碼,但是你要學會這麼做,這也需要高度的自律。
本文所討論的主題很淺顯,大多數人在上大學一年級的時候已經學過了。難在從知道這些東西到實際花時間遵循它們,再到把它們記在心裡。這就是為什麼所有在Ronimo實習過的人學到的最重要的東西不是知識,而是自律。
免費領取LAMP兄弟連原創PHP影片教學光碟/《細說PHP》精要版,詳情諮詢官網客服:
http: //www.lampbrother.nethttp://yun.itxdl.cn/online/cto/index.php?u=5 這,是一個牛XX的課程 🎜> CTO課程
http://yun.itxdl.cn/online/server/index. php?u=5 行動網路伺服器端開發課程
http://yun.itxdl.cn/online/weixin/index.php?u=5 微信開發課程
微信發展課程>http://yun.itxdl.cn/online/yingxiao/index.php?u=5微行銷課程
http://yun.itxdl.cn/online/phpcms/index.php?u=5phpcms
二次開發課程
|