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

2007年11月1日 星期四

Programming Habits 1

發現一篇關於程式設計的好文章,可以當作做好編程工作的內功心法,試著將其譯成中文,原作著為 Alexey Radul,目前是MIT的博士班研究生,原著請參考附件連結。

Over the years, I have discovered many things about the art of programming. Some I later discovered to be wrong, others I forgot and then rediscovered, others yet were discoveries of the extent of what I must yet discover. I also developed a set of habits in the domain of administering programming projects, whether they be my own, or by a small group, or larger, corporate affairs. These habits are, on the one hand, essential to the success of any software (that is not so small or so lucky that it manages regardless by sheer chance), on the other hand sufficiently easy to describe as to fit in a single essay, and on the third hand not known and loved as universally as they should be. Therefore, I wrote that single essay, and you are now reading it.

數年以來,我發現許多關於程式設計的藝術。 其中有一些是我之後發現是錯誤的,也有些是我忘記了然後又再想起,更有些是從我已知的知識再加以擴充延展而得。 我也在程式專案管理的領域中找到一些好習慣,無論他們是我自己所發現的或藉助一個小組而來,又或是從更大的企業專案中獲得。 這些習慣一方面是任何成功軟體所不可或缺的 (不是那種太小或太幸運而不需特別管理的軟體), 另一方面它們也十分簡單到容易在一篇文章中描述,更另一方面是它們還未受到世人應有的關注和喜愛。 因此,我寫了這一篇論文,而且你現在正在讀著它。

This document is organized as a collection of individual, bite-sized pieces of advice, grouped about six general topics. One reason for this is that they interact with each other, enough that it is impossible to write them down linearly, without forward references. The other reason is to allow you to jump around, to skip the bits you already know, to revisit bits you want to think about again, or to just run down the list without having to sift through the explanations.

這篇文章是以獨立的、片段式的忠告所組成,並且匯聚成六個主題。 這麼做的一個理由是文章內容與彼此充份互動,不可能直線地把他們依順寫下來而不往後方參考。 另一個理由是允許你得以跳躍式閱讀,略過你已經知道的部份,重訪想再複習的地方,或僅僅略讀標題而不詳看內容。

Version Control 版本控制

Version Control is a means to systematically track the history of a piece of software as it is being developed. This task is carried out by a thing called a version control system, such as CVS or Subversion. Said thing maintains, explicitly or otherwise, a history of the code being controlled, and provides operations to acquire (usually called check out) the current version of the code, to check in or commit one's modifications to it, and to update one's working copy to incorporate changes made by others. The version control system also provides functions for examining the history of the code in various ways, for undoing various changes made and/or returning to previous points in the software's history, and for resolving conflicts (two people changing the same code at the same time in different ways).

版本控制意指系統性地追蹤一個軟體的發展歷史。 這個任務由一個叫做版本控制系統,像是 CVS 或 Subversion, 的東西所進行。 明白地或是暗中地維護著程式碼的修訂歷史,而且提供獲得 (通常被稱為簽出)程式碼的目前版本,簽入或交付某人的修改,而且合併他人的修改至某人的工作複本上的功能。這個版本控制系統也提供回覆至先前程式版本與解決衝突(二個人同時針對相同的內容作修改)的功能。

~待續

2007年10月29日 星期一

TeeChart for .Net 與 Dandus .Net 的比較

TeeChart for .Net 與 Dandus .Net 都是執行於Asp.Net上的圖表元件,二者皆提供豐富的Web Chart的能力,最近研究了二者間的差異,有了心得如下...
在經過約三小時的測試TeeChart ActiveX v8 Evaluation之後,
並且綜合之前TeeChart for .NET v3 EVALUATION的使用經驗,
我強烈認為TeeChart 並不是一個好的Web Chart Tool,
並且建議使用Dundas,整理有關TeeChart 的問題如下:
  1. 不論是TeeChart ActiveX v8 Evaluation或是TeeChart for .NET v3 EVALUATION,安裝後的程式都存在嚴重的問題,或許我們會質疑這些都是EVALUATION版才有的問題,但我在乎的是該公司的產品品質,連一個全世界都能Download的評估版都這麼慘,我不敢相信其正式版會好到哪?
    問題簡列如下:
    1. TeeChart ActiveX v8 Evaluation: 功能目錄中包含不可執行的前版(v7.0)程式
    2. TeeChart ActiveX v8 Evaluation: 的Example 竟然是VS.NET 2003的專案,而不是VS.NET 2005的專案
    3. TeeChart ActiveX v8 Evaluation: 的Example 程式中毫無註解
    4. TeeChart for .NET v3 EVALUATION: Example 所有DEMO程式執行後竟然會當,查原因是出在元件本身的問題,如果客戶不信,我可以當場DEMO
  2. TeeChart for .NET 不支援Ajax, 這表示所有與Client端的互動,都必需以Post back的方式處理,別說其技術落後,使用觀感更是不佳
  3. TeeChart ActiveX 與 TeeChart for .NET 都無.Net特有的DataSource ID的觀念,其資料來源不能直接套用.Net的DataBinding架構
  4. 到目前為止我找不到簡單的方法將圖形複製到剪貼簿的功能
  5. 這是我們自己的問題: 我對於ActiveX的實作經驗不足,摸索期可能會較長
  6. 以上是我認為較嚴重的問題,其它可能較為次要的問題如下,雖說次要,但未來是否會變的重要也不一定:
    1. 美工繪圖的質感不佳,與Dandus有一段落差
    2. 沒有Toolbar功能,以便利使用者執行操作
    3. 範例,教學和Dandus相比,明顯較差,這會牽涉到日後開發過程中遇到問題或需求的解決速度
我的結論是,我認為TeeChart 並不是一個適合在ASP.Net平台上使用的圖表元件,或許過去它在Delphi或其它平台上有良好表現,但ASP.Net平台是一個全新,完全不同架構的環境,單機程式和WEB程式的觀念有如天差地別,以過去在Delphi使用過而推論其在ASP.Net也OK,是一種很不專業的想法,應該完全重新放空,將各種元件在同一起點重新檢視才對.就如同前面提過的 ,TeeChart 並不是一個專為ASP.Net平台所設計的元件,它像是從過去版本改良成能支援ASP.Net罷了,任何熟悉ASP.Net的人一比較二者一下子就能感覺出來.
我有發現另一個圖表元件-- ComponentArt http://www.componentart.com/ , 但目前感覺是它的重點在3D美工, 比DANDUS還漂亮, 但沒有2D, 這並不是目前這個專案的需求, 所以可以待日後再說.
最後,DANDUS能支援目前所需的功能, 又切合ASP.NET的開發架構 (DataSource),而TeeChart的模糊空間仍多,複製到剪貼簿的功能還找不到解法,如果棄DANDUS而選TeeChart,我覺得十分不智.