2008年5月2日 星期五

程式撰寫風格 Coding Style

程式撰寫風格 Coding Style 內容參考:
http://www.csharpfriends.com/Articles/getArticle.aspx?articleID=336#3 一 縮排 Indentation

折行 Wrapping Lines

每行程式碼最好在 80 個字母以內,且絕不超過 120 字母 一旦超過80個字母,就必需開始考慮折行, 折行的原則如下:
  • 在逗點之後折行
  • 在運算子之後折行 (*、/、%、+、-...)
  • 優先於高等級處折行
  • 折行後新行開頭對齊前行轉折處等級
範例:
var = a * b / (c - g + f)
+ 4 * z;
var = a * b /
(c - g + f) + 4 * z;

空白 White Space

縮排符號必需以空白字元表示,而不以Tab表示,建議啟用編輯器將Tab轉換成空白字元的設定. 每個等級的縮排長度為 4 個空白字元. 以空白字元代替Tab的好處如下:
  • 不因編輯器不同而呈現不同結果
  • 有利於折行之後的對齊

二 註解 Comment

  • 針對程式碼使用單行註解(',REM, //, #)
  • 針對大篇幅的說明段落或文章使用區塊註解(/* ... */)
  • 針對類別或函式的開頭說明,使用XML註解
  • C# Java
    /// <summary> /// This class ... /// </summary> /** <summary> This class... </summary> */

三 宣告 Declarations

每行只有一個宣告 Number of Declarations per Line

好處:
  • 方便為每個宣告加入註解
  • 方便編輯 (刪除或標示為註解)
  • 清楚
範例: int level; // indentation level int size; // size of table

初始化 Initialization

愈早為變數宣告設定初始值愈好,例如: string name = myObject.Name; 或 int count = 16; 有以下好處:
  • 增加執行時期的效率
  • 避免忘記初始化造成 NullPointerException

除了C, C++, 在C#,VB.Net或Java等種式語言中,儘可能重覆使用變數,例如千萬不要: for (int i = 0 to 100) { BigObject obj = new BigObject();

string name = "Name " + i.ToString(); obj.SetIndex(i) ... } 要改為: BigObject obj = new BigObject();

string name = null; for (int i = 0 to 100) {

name = "Name " + i.ToString(); obj.SetIndex(i); ... } 在.Net中, 多使用using,例如: using (OpenFileDialog openFileDialog = new OpenFileDialog()) { ... }

類別,介面和方法的宣告 Class and Interface Declarations

類別和介面的宣告請遵守以下規範:
  • 方法名稱與左括弧"("之間不要有空白
  • 類別,介面和方法的大括弧"{"和"}"要獨立於一行, 方法或類別內的區塊的左大括弧"{"則要同行,如迴圈,陣列,If或Enum.
  • 成對的"{"和"}"要位於相同的縮排位置
  • 每個類別,介面和方法的區塊間要間隔一行空白
範例: Class MySample : MyClass, IMyInterface { int myInt; boolean isInc; public MySample(int myInt) { this.myInt = myInt ; } void Inc() { if (isInc) { ++myInt; } } void SetIsInc(boolean inc) { isInc = inc; } }

四 陳述式 Statements

簡單性 Simple Statements

每行只有一個陳述式

If-ElseIf-Else 的格式

  • if (condition) { DoSomething(); ... } else if (condition) { DoSomethingOther(); ... } else { DoSomethingOtherAgain(); ... }
  • 儘管只有一行的內容,也必需以{ }包裝起來: if (condition) { DoOnlyOneThing(); } 好處在於,除了清楚且不容易出錯,也使後續新增內容時容易維護.
  • 如果條件判斷式已經為Boolean型別,則不需再加以判斷其真偽,例如: 要這樣寫: void Increase() { if (isInc) { ++myIndex; } } 而非這樣寫: void Increase() { if (isInc == true) { ++myIndex; } }

For / Foreach Statements

  • 基本形式如下: for (int i = 0; i < 5; ++i) { ... } foreach (int i in IntList) { ... }
  • 如果只有一行的句子,如下: for (initialization; condition; update); 請考慮用while表示: initialization; while (condition) { update; }

While/Do-While Statements

  • 基本形式如下: while (condition) { ... }
  • 空的while句子如下: while (condition);
  • do-while基本形式如下: do { ... } while (condition);

Switch Statements

  • 基本形式如下: switch (condition) { case A: ... break; case B: ... break; default: ... break; }
  • 為避免錯誤及增加可讀性,default條件務必放在最後,且要加上break.

五 空白 White Space

空行 Blank Lines

適當的空行可以增加可讀性,使用一個空行的時機如下:
  • Method or Property 之間
  • Class or Interface 之間
  • Local variables 的宣告區之後
  • Logical sections inside a method.
在逗點或分號之後應該要有一個空白,例如: TestMethod(a, b, c); 不要使用: TestMethod(a,b,c) 或 TestMethod( a, b, c ); 以一個空白包圍運算子(除了單獨運算子++,--或!等),例如: a = b; 不要使用 a=b; for (int i = 0; i < 10; ++i) 不要使用 for (int i=0; i<10; ++i) 或 for(int i=0;i<10;++i)

六 命名規範 Naming Conventions

大小寫風格 Capitalization Styles 介紹


Pascal Casing Camel Casing Upper Casing
說明 每個單字的開頭大寫 除了第一個單字的開頭小寫,每個單字的開頭大寫 所有字母皆大寫,單字間以底線"_"區隔
範例 PascalCasing camelCasing UPPER_CASING

命名指引 Naming Guidelines

  • 不要將型別資訊加入名稱中,例如不要命名 IntegerIndex 或 NameString
  • 不要使用匈牙利命名法,除非使用C或C++
  • 在Windows介面程式中,請將控制項的完整名稱或適當的簡稱加在變數名稱後方,例如: System.Windows.Forms.Button cancelButton; System.Windows.Forms.Button findBtn; System.Windows.Forms.TextBox nameTextBox;
  • 縮寫長度在二個字母以內全部大寫,三個字母以上僅開頭大寫,例如: NationUK, NationUsa, TsmcProject, CAProject, GpgSecurity, HRDepartment

Class Naming Guidelines

  • Class名稱應為名詞集合或名詞片語
  • 使用 Pascal Casing
  • 不要把"Class"加入名稱中

Interface Naming Guidelines

  • Interface 名稱應為名詞集合或名詞片語
  • 使用 Pascal Casing
  • 開頭一律為大寫 I

Enum Naming Guidelines

  • 使用 Pascal Casing 在Enum的型別名或內容中
  • 內容或型別中不要出現"Enum"
  • Enum的型別名表示為單數而非複數

Method Names

  • 使用動詞或動詞片語
  • .Net 使用 Pascal Casing, Java使用Camel Casing

Property Names

  • 使用名詞集合或名詞片語
  • 使用 Pascal Casing

Event Names

  • 使用sender和e做為EventHandler的參數名
  • 使用 Pascal Casing
  • Event名稱使用現在進行式或過去式,以清楚表示事件發生的時間點
  • 儘可能以動詞命名Event

Capitalization summary

Type Case Notes
Class / Struct Pascal Casing
Interface Pascal Casing Starts with I
Enum values Pascal Casing
Enum type Pascal Casing
Events Pascal Casing
Exception class Pascal Casing End with Exception
Public Fields Pascal Casing
Methods Pascal Casing
Namespace Pascal Casing
Property Pascal Casing
Protected / Private Fields Camel Casing
Parameters Camel Casing
Local variables Camel Casing
Const variables Upper Casing
其它
  • 只有在迴圈中才使用i,j,k,m等單一字母的變數,且用途也僅限於計數或索引的功能
程式碼範例 for (int i = 1; i < num; ++i) { meetsCriteria[i] = true; } for (int i = 2; i < num / 2; ++i) { int j = i + i; while (j <= num) { meetsCriteria[j] = false; j += i; } } for (int i = 0; i < num; ++i) { if (meetsCriteria[i]) { Console.WriteLine(i + " meets criteria"); } } 可以試著用更好的名稱取代單一字母代碼: for (int primeCandidate = 1; primeCandidate < num; ++primeCandidate) { isPrime[primeCandidate] = true; } for (int factor = 2; factor < num / 2; ++factor) { int factorableNumber = factor + factor; while (factorableNumber <= num) { isPrime[factorableNumber] = false; factorableNumber += factor; } } for (int primeCandidate = 0; primeCandidate < num; ++primeCandidate) { if (isPrime[primeCandidate]) { Console.WriteLine(primeCandidate + " is prime."); } }

七 其它 Others

  • 一個函式是否只能有一個返回點? 亦即不可在中途Return 建議: 儘可能如此,但不一定.一切以程式簡單清楚為原則.
  • No 'magic' Numbers

沒有留言: