2011年2月6日 星期日

程式碼撰寫風格之命名原則

在之前公司制定的一些程式碼撰寫規範與風格,因為是使用vb.net,因此一些規範是基於.net的ide環境下所以制定的,並不適合於其它的的IDE環境。

.net的IDE發展到現在,己經有很多功能非常好用,例如在以往為了方便看程式碼時,可以立即區別變數型別,我們都會要求在變數命名時,在開頭加上區別型別的符號,如integer會在開頭加上i,但在.net的IDE要知道變數的型別非常容易,只要滑鼠移到變數上就會顯示了,所以根本不需要在前變數前加上區別型別的符號。


命名用字原則

1. 首重可讀性,應以別人看得懂的方向來命名,使用簡單明瞭的單字及片語。
2. 非專有名詞或大家都熟知的縮寫,應避免使用。
3. 勿任意使用縮寫字,除非此縮寫是專有名詞或專案成員都有共識的命名,即使名稱過長,也不要任意創造縮寫。
4. 複合字應正確使用大小寫,例如:
正確:Checksum 錯誤:CheckSum
正確:Database 錯誤:DataBase
正確:SqlDatabase 錯誤:Sqldatabase
正確:SqlDbType 錯誤:SqlDBType (DB為縮寫字,非專有名詞)
正確:IOState 錯誤:IoState (IO是專有名詞,Upper Case)
正確:VpgState 錯誤:VPGState (VPG企業文化專有名詞,但超過三個字,Upper Case)

5. 複合字無字數限制,以能明白其意義為原則。若字數過多到影響閱讀速度時,應改用其它英文單字替代。
6. 除了常數(Constant)的命名外,不應該使用底線 _ 符號。
7. 除了控制項的命名外,不要使用匈牙利命名法。

變數宣告

1. 應使用Camel Case方法宣告變數。可以方便在閱讀時,只要看到是小寫開頭的內容就可以判斷一定是變數。
2. 在Class內宣告的全域變數,應加上字首小寫英文字母m且不應該有底線_。方便在閱讀時,透過m字首可以即時知道此變數為全域變數,修改此全域變數的內容,可能會影響其它函式的運作結果。

Private mCount As Integer
Private mItems As New ArrayList

3. 宣告在函式內的變數和Function的輸入參數,應使用Camel Case方法宣告。方便在閱讀時,可以即時知道此變數為函式內的區域變數,作用範圍只限於此函式內。

Public Sub DownScenario(ByVal index As Integer)
Dim scenario As Scenario = Me.mScenarios(index)
Me.mScenarios.Remove(scenario)
Me.mScenarios.Insert(index + 1, scenario)
End Sub

4. 全域變數宣告時,應使用Private,不要使用Dim來定義全域變數。因為使用Dim來宣告全域變數,變數會被定義成Public。Class內的全域變數也不應該宣告成Public。

Private mCount As Integer (正確)
Dim mCount As Integer (錯誤)

5. 控制項在宣告時,應加上下表所定義的字首。方便在閱讀時,即時知道是在對控制項做存取,也可以在Coding時,透過.NET提供的Intellisense功能,減少打字時間,加速開發。

字首 控制項  字首 控制項  字首 控制項
btn Button img ImageList rad RadioButton
chk CheckBox lbl Label rtxt RichTextBox
cbo ComboBox llbl LinkLabel sbr ScrollBar
cmnu ContextMenu lst ListBox spl Splitter
dgv DataGridView lstv ListView bar StatusBar
ds DataSet mnu MainMenu tab TabControl
dvw DataView mi MenuItem txt Textbox
dud DomainUpDown nico NotifyIcon tbr ToolBar
err ErrorProvider nud NumericUpDown tip ToolTip
grd Grid pic PictureBox trk TrackBar
grp GroupBox pro Process trv TreeView
hlp HelpProvider prg ProgressBar

(以上列出常用控制項,有不足處可再增加)

6. 為變數命名時,應注意:
  • 首重可讀性,應使用簡單明瞭的單字。
  • 避免使用型別名稱來當參數名稱,參數名稱的命名方式應該是用來說明其意義,而不是說明其型別。在.Net的開發環境下,將滑鼠指到變數就會顯示其型別,所以不需要在變數名稱上再表示型別。
  • 變數應為名詞,不應為動詞,即變數是用來代表人、事、地或物,並非代表動作。
  • 變數為集合時,可適當的使用複數。Ex. items、algorithms。
  • 當變數是用來作為旗標(Boolean)時,應以is、has、should、can為開頭以增加可讀性,例如isOK、isRunning、isNull、mIsMeasuring(全域)。
  • 變數名稱應該具有意義,勿使用沒有意義的名稱。For迴圏中用來代表index的i、j是例外,因為它已是大家習慣的用法。
Dim count As Integer (正確)
Dim c As Integer (錯誤)
Dim index As Integer (正確)
Dim i As Integer (錯誤)
For i as Interger = 0 To 10 (正確)
‘Do Something
End For

7. Delegate Function命名應簡寫為delXXXX。


常數Constant宣告

1. 使用Upper case,每一個字母都大寫,並且每一個單字應使用底線 _ 分隔。例如:CAMERA_GAIN。
2. 在宣告時,便給與值。

Private Const CAMERA_GAIN As Integer = 10


屬性Property宣告

1. 應使用Pascal Case方法宣告。
2. 應為名詞,表示人、事、地或物。Ex. Name、Width、ActionList。錯誤的命名:GetName,AddItem。
3. 不應該有WriteOnly的屬性(Property),應使用Sub來取代WriteOnly Property。


事件Event宣告

1. 使用Pascal Case。
2. 以動詞命名事件。使用動名詞 (動詞的 "ing" 形式) 來建立事件名稱,表示事件前;並以過去式動詞表示事件後之概念,不要使用Before或After字首。例如,Close動作,則可以在動作前命名為Closing和動作後命名為Closed。

Public Event Closing() (正確)
Public Event BeforeClose() (錯誤)
Public Event Closed() (正確)
Public Event AfterClose() (錯誤)

3. 在事件處理常式名稱上使用EventHandler後置字元。

Private Sub ClosedEventHandler()
'Do something
End Sub



方法Method宣告

1. 應使用Pascal Case方法宣告。
2. 使用動詞/動詞片語來表示。Ex. DoJob、UpdateData、GetName、AddItem。
3. 儘量避免沒有參數輸入的Function,可以使用ReadOnly的Property來代替。但若Function內有過長的Code或計算時間過久則不適合使用Property代替。在可讀性的前提下,若使用GetXXX Function來表示會更為直觀時,應選則使用Function而不考慮使用Property。
4. 方法名稱應能完整表達其內容的動作,以增加程式的可讀性。但若類別本身的名稱已明確的表示其職責時,可以使用較為簡潔的方法名稱。例如:

正確:工人.WashCar 錯誤:工人.Wash
正確:洗車工人.Wash 錯誤:洗車工人.WashCar


列舉Enum宣告

1. 應使用Pascal Case方法宣告。
2. 不要在字尾或字首加上Enum。
3. 不要將Public Enum宣告在類別內,應宣告在NameSpace內,Private Enum不在此限制。因為巢狀的設計會讓使用Enum時,有過長的程式碼。

Dim value As Class.EnumType = Class.EnumType.State1 (宣告在類別內,程式碼較長)
Dim value As EnumType = EnumType.State1 (宣告在NameSpace下)

4. Enum中一定要有一個成員,其值為零。方便宣告時,有初始值。
5. 若非特殊情況下,應明確的設定Enum成員的值。

Public Enum StatusType
OK = 0
[Error] = 1
Busy = 2
End Enum


Interface宣告

1. 應使用Pascal Case方法宣告。
2. 少用縮寫。
3. Interface的字首一定是I。
4. 使用名詞/名詞片語、或形容詞來描述行為。例如:IComponent(名詞),ICustomAttributeProvider(名詞片語),IComparable(形容詞)。
5. Interface內應避免過多或過於複雜的方法與應用。


類別Class宣告

1. 應使用Pascal Case方法宣告。
2. 名稱不應與Namespaces名稱相同,以避免萬一引用相同名稱的Namespaces時,有所混淆。
3. Event應宣告在類別的最上方,以方便瀏覽此類別時可以快速知道有提供那些事件。
4. 類別內的全域變數應宣告在使用此變數的方法附近。在.Net的開發環境下,可以透過滑鼠右鍵的移至定義,快速找到宣告此變數的地方,但若宣告的地方與原本瀏覽的地方相距太遠,將會浪費時間在移回原地方上。
5. Property應宣告在方法之前,並且統一管理。
6. 避免使用巢狀的設計,例如在類別內宣告類別或列舉。巢狀設計會增加耦合程度,並且增加沒有意義的程式碼(請參考列舉Enum宣告的第三項)。

沒有留言:

張貼留言