24小时热门版块排行榜    

查看: 1352  |  回复: 5
当前只显示满足指定条件的回帖,点击这里查看本话题的所有回帖

zyj8119

木虫 (著名写手)

[交流] 【转帖】Delphi代码的标准风格 已有4人参与

我们承认许多好的已经确定的工作室或个人,拥有他们自己的和本文里所说的不同的编程习惯, 但是,我们强烈建议你使用一个工具将你的代码转换为Borland风格的代码,然后再提交给Borland,Project JEDI或其他任何公开的源代码知识库。我们不想强迫你改变你的习惯,但我们坚持所有同Borland产品一起工作的的代码遵循本文描述的习惯。
对象Pascal是一种优美的设计语言。较强的可读性就是它的一个优点。本文设计的标准将增强对象Pascal代码的可读性。当开发人员遵从本文展现的这些简单的习惯,他们也将成为标准,这将有益于所有的Delphi开发人员使用统一的易读的代码风格。执行这些标准的努力将增加开发人员的源代码的价值,特别是在维护和调试循环阶段。
尽管我们相信并且赞美本文所宣扬的风格,但我们没有必要支持它,因为它本身是正确的而其它的则是错误的。然而我们相信绝大多数开发人员遵从的标准是有它的功效的,所以我们仍然支持并维护该风格。人类的大脑总在适应标准,并且找寻方法去快速组织所熟悉的模式,从而快速而有效地理解其含义。正是因这种要求而建立的标准将使大量的人尽可能容易的阅读代码。如果在初次使用我们的指导方针是感到陌生,那么我们请你坚持一会儿,你会发现你也变得习惯了。或者,如果你愿意,你也可以保持你自己的风格,并通过一个遵从我们标准的程序来转换,然后你可以将你的代码提交给Borland或其他知识库了。
一些文本编辑器,象Visual SlickEdit可以帮助你按照一定的风格来格式化你的代码。

一个免费的由Egbert van Nes开发的格式化程序可以在以下的连接获得:
http://www.slm.wau.nl/wkao/delforexp.html

另一个针对Delphi的商业化程序是crackerJax:
http://www.k.NETicsoftware.com/html/products.html

----------------------------------------


1.0 介绍
本文不是为Object Pascal语言定义语法规则的一种尝试。例如:在else前面放置封号";"是违法的;编译器不允许这种用法。所以我不会在本文中展示语法规则。本文旨在在语言提供选择的地方定义适当的行为习惯。我通常在只有一种控制方法的地方保持沉默。

1.1 背景
在本文出现的指导方针基于Delphi源代码的一部分。Delphi源代码恰好遵循这些指导方针。如果你发现了违反这些原则的情况,那么应该是这些原则而不是那些不确定的源代码成为你的指导方针。然而,你可以使用这些原代码作为这些原则的补充,至少它可以帮助你得到关于你自己的代码的形式的一般看法。

1.2 感谢
本文这些格式是基于已完成的为Java语言定义的风格标准的工作的。Java在规则上对格式化Object Pascal源代码是没有任何影响的,但在Sun网站上的文档是本文的基础。 在某些特殊的地方本文的风格和格式受到"A Coding Style Guide for Java WorkShop and Java Studio Programming"(Achut Reddy, 《Java车间和Java工作室的编码向导》)的很大启发。该文章可在该URL找到:http://www.sun.com/workshop/java/wp-coding
Delphi小组为本文的完成做出了重大贡献,事实上,如果没有它们的帮助,本文是无法完成的。

2.0 源文件
Object Pascal源代码主要被分成单源文件和项目文件,他们都遵从相同的习惯。Delphi项目文件有一个.DPR的扩展名。它是项目的主文件。任何在项目中使用的单元文件都有一个.PAS的扩展名。其它的文件,象批处理文件、HTML文件或者DLLs也可以在项目中扮演一个角色,但本文只涉及项目文件和单元文件。

2.1 源文件命名
Object Pascal支持长文件名。如果你使用几个单词来形成一个单一的名称,那么最好是为每个单词使用大写的开头字母:MyFile.pas。这被认为是插入式大写或驼峰式大写。扩展名应当使用小写形式。由于历史原因,Delphi源代码经常使用8:3式命名模式,但开发人员不必为上述规则所限制而转向Delphi小组的用法。
如果你正在翻译一个C/C++头文件,那么你翻译的Pascal文件要与C/C++头文件保持相同的主文件名,扩展名用.PAS。例如:windows.h -> Windows.pas。如果Pascal语法强迫你将几个头文件组合到一个单一的单元文件中,那么包含其他头文件的那个头文件的文件名将作为新单元文件的名称。例如:Windows.h包含了WinBase.h文件,则新的单元文件名为Windows.pas.

2.2 源文件组织
所有的Object Pascal单元文件应当按照以下的顺序包含下列元素:
版权/标识块注释
单元名
接口段
实现部分
一个结束符"end."

每个部分之间至少空一行。

其它的元素应当被结构化成你认为最适当的顺序。但版权应当出现在文件的最开始,然后是单元名,然后是任何条件定义、编译器指示符或包含语句,然后是uses字句:



{*******************************************************}
{ }
{ Borland Delphi Visual Component Library }
{ }
{ Copyright (c) 1995,98 Inprise Corporation }
{ }
{*******************************************************}

unit Buttons;

{$S-,W-,R-}
{$C PRELOAD}

interface

uses
Windows, Messages, Classes,
Controls, Forms, Graphics,
StdCtrls, ExtCtrls, CommCtrl;






如果你将type段放到const段之前,或者将它们两者混合,那是没有什么影响的。

实现部分需要首先将implementation写出来,然后是uses字句,然后是其它的包含声明或别的指示符:



implementation

uses
Consts, SysUtils, ActnList,
ImgList;






{$R BUTTONS.RES}

2.2.1 版权/标识块注释
每一个源文件都应当以一个包含版本信息和标准版权布告块注释开始。版本信息可以象下面这样:



{*******************************************************}
{ }
{ Widgets Galore }
{ }
{ Copyright (c) 1995,98 Your Company }
{ }
{*******************************************************}






版权布告至少需要包含以下行:
版权所有(C) 年份 版权所有者

如果你是为Borland开发软件的第三方,你可以在版权的最后加入你自己的名字:



{*******************************************************}
{ }
{ Borland Delphi Visual Component Library }
{ Copyright (c) 1995,99 Borland International }
{ Created by Project JEDI }
{ }
{*******************************************************}






2.2.2 unit声明
每一个单元文件要有一个unit声明。unit是一个保留字,因此它需要小写。单元的名称可以是大小写混合的,但必须和单元文件的文件名相同。例如:
unit MyUnit;

则单元文件的名称应当为MyUnit.pas。在文件系统中,它作为这个文件的入口。

2.2.3 uses声明
在单元内部,uses声明应当使用小些的uses引导。被引用的单元名要遵循在他自己的单元中被定义时使用的大写习惯:
uses MyUnit;
每一个单元名被一个逗号同其相邻的单元名分开,最后一个单元名后面跟一个分号:



uses
Windows, SysUtils, Classes, Graphics, Controls, Forms,
TypInfo;
在uses的下一行开始加入单元名和在uses后面直接加入单元名同样都是正确的。
uses Windows, SysUtils, Classes, Graphics, Controls, Forms,
TypInfo;




你可以格式化你的单元名列表,可以在80个字符限制下换行,或者每个单元名一行。

2.2.4 类和接口定义
类的定义以两个空格开始,然后是一个前缀"T"。 前缀要大写,每个内嵌的单词要大写开头。不要在Object Pascal源代码中使用制表符"Tab"。例:
TMyClass
在标识符之后接一个空格,然后是等号,然后是class单词,class要小写:
TMyClass = class
如果你的类是从祖先继承来的,则需要加入包含着祖先类的左右括号:
TMyClass = class(TObject)
范围指示符离页边两个空格,并以下面的顺序出现:
TMyClass = clss(TObject)
private
protect
public
published
end;
数据通常只在private段声明,并且它们的标识符以"F"开始。所有此类的声明离页边4个空格:



TMyClass = class(TObject)
private
FMyDate: Integer;
function GetDate: Integer;
procedure SetData(Value: Integer);
public
published
property MyData: Integer read GetData write SetData;
end;




接口遵从同类相同的规则,除了你应当忽略范围指示符和私有数据,并且使用interface单词代替class单词。
命名习惯
除了保留字和指示符是小写外,所有的Pascal标识符应当使用驼峰式格式,即每个标识符开头字母要大写,内嵌单词的首字母也要大写,只取首字母的缩写词也一样。
MyIdentifier
MyFTPClass
对此规则主要的例外是头文件翻译的情况,应当遵循在原头文件中的命名习惯。例如:
WM_LBUTTONDOWN,不要写成wm_LButtonDown.
除了头文件翻译外,不要使用下划线分割单词。类名应当是名词或名词短语。接口或类的名称依赖于接口的显而易见的目的、用途。

好的名字:
Addressform, ArrayIndexOutOfBoundsException
低劣的名字:
ManageLayout //使用动词短语
delphi_is_new_to_me //使用下划线

3.1 单元命名
参见单元声明

3.2 类/接口命名
参见类/接口声明

3.3 域/字段命名
使用驼峰式格式。以大写的"F"开始,并且在private中声明所有的数据,使用属性或获取者(getter)和安装者(setter)来提供公共的存取操作。例如:使用名字GetSomething来命名一个返回内部域/字段值的函数,使用SetSomething来命名一个设置域/字段值的过程。
不要在const段全部使用大写,除非是头文件翻译的需要。
Delphi是在加利福尼亚开发的,所有我们阻止记号的使用,除非是头文件翻译的需要。
正确:
FMyString: string;
不正确:
lpstrMyString: string;
当然在枚举类型定义中保留了匈牙利命名法:
TBitBtnKind = (bkCustom, bkOK, bkCancel, bkHelp,
bkYes, bkNo, bkClose, bkAbort, bkRetry,
bkignore, bkAll);
在这种情况下字符bk被插入到这个枚举类型的每一个元素前。bk意味着ButtonKind。
在考虑命名习惯时,要避免使用单个字符的名称,但零时变量和循环变量除外。
避免使用"l"(L)变量,因为它和"1"(one)无论在打印机还是在显示器上都难以分辨。

3.4 方法命名
方法命名也使用驼峰格式。方法命名习惯同非常量域的命名方法是相同的,但可以从上下文区分它们。方法命名应当强制使用动词或动词短语。例如:
//好的方法命名:
ShowStatus, DrawCircle, AddLayoutComponent
//差的方法命名:
MouseButton //名词短语,没有描述功能
drawCircle //以小写字母开头
add_layout_component //使用了下划线

//以下方法的功能不够明确。它是开始运行一个服务呢(更好:StartServer)还是判断一个服务是否在运行(更好:IsServerRunning)?
ServerRunning //动词短语,但不是命令
一个获取或者设置一些类属性的方法应当分别被称为GetProperty或者SetProperty,Property代表该属性的名称。例如:
GetHeight, SetHeight
一个测试类的布尔属性的方法应当被命名为IsVisible,Visible代表属性的名称。例如:
IsResizable, IsVisible

3.5 局部变量命名
除了不使用"F"外,局部变量的命名规则同域/字段的命名规则一样。参见3.3节。

3.6 保留字
保留字和指示符要全部小写。这有时有些混乱。例如:Integer是一个标识符,并且以首字母大写出现。而string保留字则全部小写。

3.7 类型声明
所有类型名称声明以字母T开始,接下来和类的命名相同。

4.0 空白用法
4.1 空白行
空白行可以通过将逻辑相关的代码段分组来提高可读性。一个空白行也可以在下列地方使用:
在版权注释块之后,包声明(package),导入段(import)。
类声明之间。
方法声明之间。
4.2 空格
Object Pascal是一种非常清晰易读的语言。通常,你不需要在代码里加入很多空格来分隔行。以下几条提供了一些原则该如何使用空格:
4.2.2 不应当使用空格:
在方法名和左括号之间;
在.(dot)操作符之前或之后;
在一元操作符和它的操作数之间;
在一个类型和被它强制转换的表达式之间;
在左括号之后和右括号之前;
在左方括号之后和右方括号之前;
在一个封号前;
例如:
//正确用法:
function TMyClass.MyFunc(var Value: Integer);
MyPointer := @MyRecord;
MyClass := TMyClass(MyPointer);
MyInteger := MyIntegerArray[5];
//错误用法:
function TMyClass.MyFunc( var Value: Integer ) ;
MyPointer := @ MyRecord;
MyClass := TMyClass ( MyPointer ) ;
MyInteger := MyIntegerArray [ 5 ] ;

4.3 缩进
你应当总是为所有的缩进层次缩进两个空格。换句话说就是,第一层缩进两个空格,第二层缩进四个空格,第三层缩进六个空格……。不要使用制表符Tab。
当然,仍然有少量的例外。保留字象unit, uses, type, interface, implementation, initialization 和finalization总是顶格的。单元的最后一个end标识符也是顶格的。在项目文件中,program和主begin、end也是顶格的。在主begin..end块内则需要缩进至少两个空格。
回复此楼
好好学习,天天向上。
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

xiaoheihei366

至尊木虫 (著名写手)

★ ★
小木虫(金币+0.5):给个红包,谢谢回帖交流
dubo(金币+1): 欢迎常来程序语言版讨论 2011-06-06 15:22:06
谢谢,我也喜欢Delphi,谢谢分享。
4楼2011-02-28 09:47:57
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
相关版块跳转 我要订阅楼主 zyj8119 的主题更新
普通表情 高级回复 (可上传附件)
信息提示
请填处理意见