coding style
程式的命名與coding style討論
- Boolean變數或function的命名方式
Boolean變數或function的開頭必須使用is, can, has, should, 但如果本身是形容就不需要,像是enabled, done就無需用is開頭
- 用介系詞(of,for,from,on…)來組變數名稱
這件事情但起來單純,但很多時候大家都會忽視介系詞硬組變數名稱, 像是daysUntilDeadline就有可能被命名成DeadlineDays,如易造成誤解, 以下是我找到一些不錯的範例
var daysSinceModification = 3; // 在修改已過了3天
var workDaysPerWeek = 5; // 每週工作5天
var daysUntilDeadline = 10; // deadline前還剩10天
- 使用更具體的單位
delayedTime代表的是delay的時間,但其實單位是秒數, 所以命名上最好使用更具體的單位來優化這個命名,改寫成delayedSeconds會更好
- 捨棄i,j,k,使用更好的Iterator
一般for迴圈中我們都會使用到i, j, k,這其實不是不行, 但是如果i, j, k分別代表parent, children, toy, 那就可以用pi, ci, ti來取代i, j, k,這樣程式碼不會變長太多, 可讀性提高也較容易debug
- Function Name的prefix都是動詞
基本上function名稱全都是「動詞」 開頭但如果像是getCellSize()或calcCellSize(),可以直接省略開頭的動詞, 直接使用cellSize()即可,不過也有人堅持不能用名詞開頭,基本上團隊統一即可。
- 縮寫真的方便但並不是最好
因為不想打太長的變數或函數名稱,大家總是在縮寫, 但是有些縮寫很容易讓人搞混,對於原本就在維護這份程式的工程師或許還好, 但新進工程師會很容易困惑。
使用像是dns,url這些眾所皆知的詞沒問題,只有自己團隊才看得懂的縮寫, 除非必要,不然盡量避免使用。
不過我覺得這個看情況而定,重點是一定要有一份解釋縮寫的文件比較好。
- 如何寫註解
-
在檔案的最前頭寫上整個程式檔案大致是如何運作的檔案註解
-
除了解釋程式運作的原理外,還可以描述為什麼要用這樣子的寫法來寫, 可能是效能上的需求之類的
-
使用 TODO FIXME 等註解標籤,TODO可以標記尚未製作或是需要優化的部分, FIXME是不能運作需要修復的部分,其實我知道還有HACK, XXX 等標籤, 不過我覺得好像都歸類在TODO比較方便,不知道大家的習慣是如何?
-
在設定常數的時候給予註解其實也能幫助理解,讓開發者更有概念, 像是下面程式註解說明為什麼要設定為1000的理由
// 加上合理的限制 - 沒有人能讀那麼多文章 const int MAX_RSS_SUBSCRIPTIONS = 1000;
- 封裝條件
如果if()裡面有超長一串的判斷式,可讀性會超差, 所以可以把這個判斷式用boolean變數裝起來再判斷
boolean isMan = (user.age >= 18 && user.gender == ‘male’);
if (isMan){
// 做一位男人該做的事 >///<
}
======================================
其中最想請教大家的是function前方動詞的分類
Clean Code這本書上有說 Pick one word for one abstract concept and stick with it.
不過比較沒人整理出較為通用的詞庫對應表, 我知道這個本來就沒官方解答,但是我想聽聽看各位的經驗, 整理出我自己的一套詞庫,以下是我目前整裡的詞庫
fetch:從遠端(透過API)獲取資料,例如:fetchUsers()
load:從本地端加載資料,例如:loadFile()
calculate/calc:通過計算獲取資料,例如:calcBMI()
show:顯示物件,如showModal()、showDialog()
remove:將資料之間的關係移除,資料本身還是會存在
delete/destroy:將資料刪除,資料將會不存在
on:定義event的時候使用,像是onClick,onChange
handle:當onClick之類的event發生時所觸發的function, 例如:handleClick,如果click後面有受詞的話, 這將受詞移到click前方* 例如:handleButtonClick
剩下還有哪些詞是大家常用的呢?還請各位大大不吝分享, 我在下面放一些可能會用到的詞,大家是怎麼給這些詞定義他專屬的concept, 或是有哪些沒提到的也可以補充一下,麻煩大家給點意見了XD
get/set create: insert append add append edit: modify update complete: finish done end send: deliver, dispatch, announce, distribute, route find: search, extract, locate, recover start: launch, create, begin, open make: create, set upm build, genernate, compose, add, new
refer allenwang15: 程式的命名與coding style討論
微軟 PowerShell 指令動詞列表
微軟 PowerShell 指令動詞列表 Approved Verbs for Windows PowerShell Commands https://msdn.microsoft.com/en-us/library/ms714428.aspx
「英文不好」是個很大的題目,相對於「聽、讀」,「說、寫」的自學門檻較高。 以程式設計師來說,「寫英文」的需求可分為至少兩大方面:
- 命名
- 「名詞」: 變數(variable)、類別(class)
- 「動詞」: 函式(function) / 方法(method)
- 說明/描述
- 短文註解 (code/commit comment)
- 長篇文件(documentation) / 手冊(manual)
這個「微軟 PowerShell 指令動詞列表」當然不是唯一的標準,但它列出了許多動 詞 (尤其是程式設計領域常用的動詞) 及其使用情景的說明,可以作為「動詞命名 」的參考。
refer AmosYang: Re: [討論] 註解 用中文還是英文
Variable Name Anti-Patterns
-
Naming Scalars Like Objects
Bad example:
store = "Jason's Capsaicin Station"
Good example:
store_name = "Jason's Capsaicin Station"
Explanation: If I see a variable name like store, I think it’s an object. This problem becomes especially severe when the codebase does in fact have a class called Store and some stores are instances of that class and some stores are just store names.
-
Naming Counts Like Collections
Bad example:
products = 0
Good example:
product_count = 0
Explanation: If I see a variable called products I would probably expect its value to be a collection of some sort. I would be surprised when I tried to iterate over the collection only to discover that it’s actually an integer.
-
Naming a Variable After Its Type
Bad example:
array = []
Good example:
customers = []
Explanation: A variable called array or hash could contain pretty much anything. By choosing a name like this you’re forcing the reader to do all the thinking.
-
Overabbreviation
Bad examples:
passwd fname cust o
Good examples:
password first_name customer order
Explanation: Abbreviations like passwd violate the Principle of Least Astonishment. If I know a class has a password attribute I should be able to guess that that attribute is called password. Since passwd is pretty much totally arbitrary, it’s a practically unguessable. Plus, how valuable is it to save two keystrokes?
I have a saying: It’s better to save time thinking than to save time typing.
Exception: Abbreviations are fine when they match up with real-world abbreviations. For example, SSN, USA and admin are all fine because these are predictable and already familiar to most people.
-
Use of “Stuff Words” For Collections
Bad examples:
news[0] inventory[0]
Good examples:
articles[0] inventory_items[0]
Explanation: There are certain words that have no singular form. Examples include “stuff”, “garbage” and “laundry”. I call these “stuff words”. This anti-pattern especially applies to database table names.
-
Key/Value Mystery
Bad examples:
products.each { |key, value| puts value } products.each { |k, v| puts v }
Good example:
products.each { |name, price| puts price }
Explanation: Names like key and value have almost no meaning. There’s almost always a more purpose-revealing option.
Summary
varaible naming
-
boolean: is, can, has, should 開頭
enabled, done 不需要 is or can 那些
-
int something_count scores_sum
-
str store_name product_name
-
array
list of customer object customers = [customer….]
用介系詞(of,for,from,on…)來組變數名稱
使用更具體的單位
rebootAfterSeconds = 60
var daysSinceModification = 3
捨棄i,j,k,使用更好的Iterator Function Name的prefix都是動詞
如何寫註解
-
在檔案的最前頭寫上整個程式檔案大致是如何運作的檔案註解
-
除了解釋程式運作的原理外,還可以描述為什麼要用這樣子的寫法來寫, 可能是效能上的需求之類的
-
使用 TODO FIXME 等註解標籤,TODO可以標記尚未製作或是需要優化的部分, FIXME是不能運作需要修復的部分,其實我知道還有HACK, XXX 等標籤, 不過我覺得好像都歸類在TODO比較方便,不知道大家的習慣是如何?
-
在設定常數的時候給予註解其實也能幫助理解,讓開發者更有概念,像是下面程式註解說明為什麼要設定為1000的理由
// 加上合理的限制 - 沒有人能讀那麼多文章
const int MAX_RSS_SUBSCRIPTIONS = 1000;
- 封裝條件; 過長的判斷式會導致可讀性變差, 判斷式子用變數包裝起來再判斷
boolean isMan = (user.age >= 18 && user.gender == ‘male’);
if (isMan){
// 做一位男人該做的事 >///<
}