delphi源程序代码规范.docx
《delphi源程序代码规范.docx》由会员分享,可在线阅读,更多相关《delphi源程序代码规范.docx(23页珍藏版)》请在冰豆网上搜索。
delphi源程序代码规范
Delphi源程序代码规范
V1.0
鼎创公司
2005-8-13
I.总则
1.1目的
为了对程序员的开发进行适当的规范化,特制定本规范。
其根本目的,是为了保证程序具有良好的、一致的结构,以期提高程序的可读性及可维护性,方便程序的测试、维护、升级等工作,同时,也培养程序员书写代码的规范性。
1.2原则
名称反映含义,形式反映结构;
1.3申明
本规范适用于采用DELPHI作开发工具的公司所有项目,程序员应严格按照本规范编写代码,如项目有确实需要的特殊要求,也必须经项目经理审核后,把该特殊要求形成文档当作本文档的随附文件一起保存。
1.4文档编写:
XXX2001年6月23日
第一次修改:
XXX2001年7月7日
第二次修改:
XXX2001年9月28日
II.代码规范
2.1项目规范
2.1.1.每一个项目的代码、文档按模块、功能必须在项目文件夹中有条理的归类存放,每个项目文件夹中均必须包含以下子文件夹:
Code:
源代码目录
Sql:
数据库脚本目录
Demodata:
演示数据目录
Userdata:
用户数据目录
Help:
帮助文档目录
Install:
安装文件目录
Document:
文档目录
Picture:
图片目录
templates:
报表模板目录
子文件夹下也必须依照详细的用途分类建立子目录。
详细的示例如下:
示例:
ProjectName
|
codesqldemodataPicturehelpinstalldocumenttemplates
||
appserverclient|
|测试文档设计文档数据字典需求分析用户文档
module1module2module3……
2.1.2.每个项目的主目录下均必须有一个项目说明文件,说明该项目的一些概要性提示和相关规范。
2.1.3.在项目文件夹下的每层每个子目录中必须有一个文件夹说明文件,说明该层文件夹及其子文件夹的分类方法和含义。
任何时候,新增一个文件夹时,均必须在同层目录下的文件夹说明文件中添加所新增文件夹的分类含义,同时创建该文件夹下的文件夹说明文件。
2.1.4.工程文件代码规范:
A.任何一个工程文件(包括动态链接库工程文件)的第一部分必须用注释的形式说明项目名称、公司版权、工程描述、版本说明、创建日期、作者以及后续更新人员。
B.除主模块、公共函数模块和公共数据模块外,所有该项目下的单元不可由项目自动创建(CREATE),在加入新单元后,必须在工程文件中删除自动CREATE的语句。
C.工程文件的其余代码遵行本文档约定的单元规范及其它代码规范;
2.2单元总体规范
2.2.1每个单元的第一部分必须用注释的形式说明项目名称、公司版权;
2.2.2必须紧接在单元名之后以注释的形式说明项目名称、模块名称、模块描述、模块版本、创建日期、作者、更新人以及TODO列表;
2.2.3在INTERFACE部分USE的单元原则上只允许DELPHI的IDE自动添加,如确需自己添加必须在引用到的单元名后用{}注释添加原因。
用于编译开关控制的伪指令插入在USES之前。
2.2.4Interface部分应当只包含需要被外部单元访问的类型、变量、过程和函数的声明,而且这些声明应当在Implementation部分之前。
2.2.5Implementation部分包含本单元私有的类型、变量、过程和函数的声明。
2.2.6除非确实需要,不要在Initialization部分写过多代码,如有代码应详细注释说明必须写在Initialization部分的原因。
2.2.7在Finalization部分释放所有在Initialization部分中分配的资源。
2.2.8除主FORM外,每个FORM单元都应当含有实例化函数(入口函数),用于创建、设置、显示和释放FORM。
FORM的变量应当从单元中移走,改在实例化函数中作为局部变量定义(要先从ProjectOptions对话框的自动生成列表中移走该FORM)。
(参见2.1.4.B)
2.2.9总体风格
缩进规则:
每级间保持两个空格。
不要将"Tab"符号存储到源文件中,原因是"Tab"字符在不同的源代码管理中宽度会有不同的定义。
在Tools|EditorOptions的General页不要选中SetTabCharacter和OptimalFill复选框,制表符"Tab"即不会被保存。
边距页宽:
边距应保持默认设置的80个字符,只要可能,长度超过一行的语句必须用逗号或运算符换行。
换行后,应缩进两个字符。
注释规则:
只有在一行的行末注释时才用//,否则均必须使用{}来注释。
空行使用:
需使用空行的地方有:
版权块、类之间、方法过程函数之间、方法内部算法分段。
空行只能用一行,多余的空行必须删除。
Begin…End:
任何情况下,Begin和End均必须各自独占一行。
End总和对应的Begin左对齐。
工具使用:
所有单元提交给版本控制工具之前必须用SourceCodeFormatter格式化过。
示例:
{*******************************************************}
{}
{项目名称}
{}
{版权所有(C)2000,2001公司名称}
{}
{*******************************************************}
unitUnitName;
{*******************************************************
项目:
模块:
描述:
版本:
日期:
作者:
更新:
TODO:
*******************************************************}
interface
{$IIS.inc}
uses
----,----,----,----,----,----,----,----,----,----,----,----;
const
--------------------;
type
--------------------;
var
--------------------;
implementation
uses
----,----,----,----;
{$R*.RES}
{$R*.DFM}
--------------------------------;
--------------------------------;
--------------------------------;
end.
2.3单元内部规范
2.3.1常量区:
A,所有常量的第一个前缀必须为C,常量必须分主题归类定义,如有多个主题,每一个主题必须加一个主题前缀。
前缀与前缀之间、前缀与名称之间用_分割。
B,每个常量的定义单独一行,在同一行上,必须用//加注释说明该常量的含义。
C,按主题归类的常量,在每个主题开始的第一行必须用{}注释主题含义。
D,示例:
Const
{主题1}
C_主题前缀1_---=----;//含义
C_主题前缀1_---=----;//含义
C_主题前缀1_---=----;//含义
C_主题前缀1_---=----;//含义
{主题2}
C_主题前缀2_---=----;//含义
C_主题前缀2_---=----;//含义
C_主题前缀2_---=----;//含义
C_主题前缀2_---=----;//含义
2.3.2类型区:
A,不提供服务的数据类型定义格式为:
T----=---------//类型含义
B,有状态并提供服务的数据类型定义格式为:
T----=class(----)//类型含义
private
--------
protected
--------
public
--------
published
--------
end;
C,原则上,数据类型及其内部方法、属性、数据定义时应按字母顺序排列。
属性的读写方法分别以Get和Set为前缀命名。
D,内部数据、属性、方法定义规则:
D1,Private区
1、所有数据放在Private区,以F打头。
2、所有事件属性对应的方法指针放在Private区,以F打头。
3、不准备被继承的属性的Get与Set方法放在Private区。
4、响应消息的方法放在Private区。
D2,Protected区
1、被子类调用的但不能被外界调用的方法与属性。
2、供子类重载的方法virtual;abstract。
D3,Public区
1、构建析构方法
2、供外界调用的方法
3、供外界调用的属性
D4,Published区
1、出现在ObjectInspector里供设计时用的属性
2、出现在ObjectInspector里供设计时用的事件响应
E,特殊的数据应在定义一行的行末用//注释其含义。
特殊的属性、方法应在定义前一行用{}注释其含义。
事件指针的定义不需注释,但事件类型定义时必须在其前一行用{}注释其含义。
2.3.3变量区
A,在变量区定义单元的全局变量。
B,每个需要注释的变量单独一行,在行末用//注释其含义。
C,同一类型且含义逻辑上不并列的变量分开定义,同一类型且含义逻辑上并列的变量在一起定义。
D,一般不鼓励使用全局变量。
在确实需要使用全局变量的时候,必须把全局变量限制在需要的环境内,如:
一个全局变量可能只在单元的Implementation部分是全局的,所以必须把其定义在该部分内。
被多个单元使用的全局数据应该被移入一个公共模块中。
E,全局变量可以在定义时直接初始化为某一个值。
注意:
所有的全局变量将自动进行零初始化,所以,不要将全局变量初始化为空值,如0,nil,'',Unassigned。
零初始化的全局变量在可执行文件中不占用空间,非零初始化的全局变量则在可执行文件中占空间。
F,变量的命名规则参见本文档后面的命名规则项。
2.3.4实现区
A,事件、过程、函数应按主题分类归集在一起,每个主题开始的第一行用{}注释该类主题。
约定归类方法如下:
同一个元件的事件应归集在一起,被事件调用或与之相关系的函数或过程应紧跟在该事件之后,函数、过程、方法之间如存在调用关系也应归集在一起,除非该函数、过程被多处调用。
被多处调用的单元内部函数、过程应归集在单元的公共过程主题内。
可以自定义归类方法,比如按实现功能归类,但如归类方法不同于本约定的,应在所有主题之前用{}注释说明归类方法。
B,每一个事件、方法必须在其代码前用{}注释说明名称、描述、参数含义、创建时间、作者、更新人、更新时间。
在事件、方法内部不同含义的算法或不同主题的代码间空一行,每段算法或主题的开始用{}注释算法或主题的目的。
关键性的算法行应在行末用//注释算法目的。
事件、方法内部的变量定义时必须遵行2.3.3约定的变量区规范。
C,SQL语句书写规则:
在SQL语句中,所有SQL保留字统一用大写,所有字段名以及数据表名全部用小写,SELECT,FROM,WHERE,ORDERBY顶格起行,各子句中要求每个字段或每个条件或每个关联单独起行,并缩进对齐,缩进两格。
示例如下:
strMasterSql:
=
'SELECTpreload.*,'+
'codelib.codenamevesselname'+
'blstatus=CASEblstatusidWHEN“1”THEN“订舱”'+
'WHEN“2”THEN“配航线”'+
'ELSE“其他”'+
'END;'+
'FROMpreload'+
'LEFTJOINcodelib'+
'ONcodelib.codecd=preload.vesselcd'+
'ANDcodelib.classid="03"';
strMasterFilter:
=
'WHEREpanycd=:
companycd'+
'ANDpreload.idno=:
idno';
strMasterOrder:
='ORDERBYpreloadno';
注意:
CASE...WHEN...THEN...ELSE...END等SQL语句的关键字用大写。
D,代码中用到数据库字段名称的地方,统一用小写。
E,元件本身的属性、事件名,要按照DELPHI自动提示的格式写。
2.4ObjectPascal语法约定
2.4.1语法杂项:
A,运算符前后要有各一个空格。
B,在开始圆括号和后一个字符,以及结束圆括号和上一个字符中不出现空格。
不要在语句中出现不必要的括号。
如if(I=42)then中,括号就是不必要的。
C,ObjectPascal语言的保留字和关键字总是小写。
D,一般不建议使用Variant和OleVariant,除非数据类型只有在运行期才能确定或获知的。
OleVariant常常用来做基于COM的程序:
Auutomation和ActiveX控制,Variant基于non-COM的程序。
E,代码中不可使用Real类型,对于浮点数,应当使用Double类型。
F,定义对象特性时,应当使用读写方法来访问。
2.4.2过程与函数
A,形参的顺序主要要考虑寄存器调用规则,最常用的参数应当作为第一个参数,按使用频率依次从左到右排。
输入参数应当位于输出参数之前。
范围大的参数应当放在范围小的参数之前,如SomeProc(Acountry,Astate,ACity)
IDE自动生成的事件句柄,参数顺序不必依此约定。
B,所有的常量参数应当标以Const标记。
C,为避免命名冲突,除调用公共模块的例程外,调用其他模块的过程、函数时应当在例程名前加该例程所在的单元名。
D,除非确实需要在使用前再初始化,否则例程的内部变量应当在例程的入口处立即初始化。
2.4.3语句规范
A,IF语句:
●在if/then/else语句中,最可能执行的情况应放在then子句中,出现可能较小的情况放在else子句。
●尽量避免使用连续的if语句,应该使用case语句来代替。
●不要嵌套5层以上的if语句。
●不要在if语句中使用多余的圆括号。
●如果if语句中存在多个条件判断,条件应该按从最快的到最慢的计算,难度依次从左到右排列整齐。
易判断者优先。
●IF语句的规范示例:
if(--------)then
-------------;
if(--------)then
begin
-------------;
-------------;
end;
if(--------)then
-------------
else
-------------;
if(--------)then
begin
-------------;
-------------;
end
else
-------------;
if(--------)then
begin
-------------;
-------------;
end
else
begin
-------------;
-------------;
end;
if(--------)then
-------------
else
if(--------)then
-------------;
B,CASE语句:
●CASE语句中,代表每种情况的常量应该按照数字或字母顺序排列。
●每种情况所对应的动作语句应当简短且通常不超过4~5行。
如果动作太复杂,应将代码放到一个单独的过程或函数中。
●CASE语句的ELSE子句只用于默认情况或错误检测。
●CASE语句的规范示例:
case--------of
--------:
-------------;
--------:
-------------;
--------:
-------------;
else-------------;
end;
case--------of
--------:
-----------------------------------------------------------------;
--------:
-----------------------------------------------------------------;
--------:
-----------------------------------------------------------------;
else
-----------------------------------------------------------------;
end;
case--------of
--------:
begin
--------------------------;
--------------------------;
--------------------------;
end;
--------:
begin
--------------------------;
--------------------------;
--------------------------;
end;
--------:
begin
--------------------------;
--------------------------;
--------------------------;
end
else
begin
-------------;
-------------;
-------------;
end;
end;
C,WHILE语句:
●不要用Exit过程来跳出一个While循环。
如果需要的话,应该使用循环条件退出循环。
●所有对While循环进行初始化的代码应当位于While入口前,且不要被无关的语句分隔开。
●While语句的规范示例:
while------do
begin
-------------;
-------------;
-------------;
end;
D,FOR语句:
●如果循环次数是确定的,应当用FOR语句代替WHILE语句。
●FOR语句的规范示例:
forI:
=--------to--------do
-------------;
forI:
=--------to--------do
begin
-------------;
-------------;
-------------;
end;
forI:
=--------to--------do
if(--------)then
begin
-------------;
-------------;
-------------;
end;
forI:
=--------to--------do
if--------then
begin
-------------;
-------------;
-------------;
end;
E,REPEAT语句:
●repeat语句和while语句类似,且遵循同样的规则。
●Repeat语句的规范示例:
repeat
-------------;
-------------;
-------------;
until------;
F,WITH语句:
●with语句应该尽量少的使用,尤其是有多个对象的WITH语句。
●With语句的规范示例:
with--------do
-------------;
with--------do
begin
-------------;
-------------;
-------------;
end;
G,try语句:
●除非是在单元的initialization/finalization部分或者对象的构造/析构中分配/释放资源,否则,凡是分配资源的地方都必须使用TRY……FINALLY语句来保证资源得到释放。
●可能的情况下,每个资源分配应当与一个try……finally结构配对。
●不可以在try…exception中使用else字句,因为这样有可能阻碍其他所有的异常发生。
●需要在发生异常时执行一些自定义的任务,才使用try……except,如果仅仅是为了显示一个错误信息,没有必要使用try……except,因为Application对象能够自动根据上下文做到这一点。
●如果要在except子句中激活默认的异常处理,可以用raise再次触发异常。
●Try语句的规范示例:
try
-------------;
-------------;
-------------;
finally
-------------;
-------------;
-------------;
end;
try
try
-------------;
-------------;
-------------;
except
-------------;
-------------;
end;
finally
-------------;
-------------;
-------------;
end;
2.5命名规范
2.5.1过程、函数的命名规则。
A,例程名以大写字母开始,且应在具有不同词义单词的第一个字母处用大写。
B,例程名应当有意义,并应尽量使用动宾词组。
C,设置输入参数值的例程名应当以Set为其前缀,获取数值的例程名应当以Get为其前缀。
D,例程的形参名称应当表达出它的用途,只要可能,形参的名称应以字母A为前缀。
E,DELPHI的IDE自动产生的事件句柄,名称和参数不可作改动。
2.5.2变量命名规则
A,变量的名称应当能表达出它的用途。
尽量不缩写,并使用名词作为变量名。
B,变量名应该用类型的缩写作为前缀,比如strMasterSql。
B,循环控制变量可以是单个字母如I、J、K,也可以使用具有含义的名称。
C,布尔变量的名称必须能清楚的表示出True和False的意义。
E,工程的全局变量应该以G_作为前缀