Delphi程序员代码风格指南精修订.docx

上传人:b****5 文档编号:4919365 上传时间:2022-12-11 格式:DOCX 页数:17 大小:23.22KB
下载 相关 举报
Delphi程序员代码风格指南精修订.docx_第1页
第1页 / 共17页
Delphi程序员代码风格指南精修订.docx_第2页
第2页 / 共17页
Delphi程序员代码风格指南精修订.docx_第3页
第3页 / 共17页
Delphi程序员代码风格指南精修订.docx_第4页
第4页 / 共17页
Delphi程序员代码风格指南精修订.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

Delphi程序员代码风格指南精修订.docx

《Delphi程序员代码风格指南精修订.docx》由会员分享,可在线阅读,更多相关《Delphi程序员代码风格指南精修订.docx(17页珍藏版)》请在冰豆网上搜索。

Delphi程序员代码风格指南精修订.docx

Delphi程序员代码风格指南精修订

集团标准化工作小组#Q8QGGQT-GX8G08Q8-GNQGJ8-MHHGN#

 

Delphi程序员代码风格指南

一.建立工程目录

首先,第一步要做的,当然是给新项目建一个单独的目录(别笑)。

目录名称与项目名称同名,或者另取一个也可,只要清楚、简练。

然后,在此目录中创建以下各个目录:

用来存放该项目相关的开发文档(需求说明,概要设计,详细设计等等等等);

用来存放Delphi源程序中的”.Dpr”,”.Pas”,”.Dfm”等文件;

该目录中存放”.Dcu”文件,将’.Pas’与’.Dcu’文件分开存放只是为了让Source目录的内容更加清楚一些;

存放工程的输出文件,比如”.Exe”,”.Dll”或者”.Ocx”等等;

用来存放日志文件;通常在这个目录中我会放一个”<项目名称>程序员日志.Txt”文件。

当然是存放工程中用到的图片的目录了。

一般情况下,这个目录是少不了的。

假如还用到其他资源,那么也一样建立各自的目录,比如Wav,比如Avi等等。

二.设置工程选项

在Delphi中创建一个新的工程,将此工程保存到Source目录中,同时:

a.选一个耐看的,与项目有些联系的图标作为这个工程的图标。

当然,这个图标可能只是临时用用的,但是总要比Delphi默认的那个难看的要好才行,要不然,怎么对得起自己

b.将ProjectOptions->Directories/Conditionals页面中的OutputDirectory设置为Bin目录;

c.将UnitoutputDirectory设置为Dcu目录。

三.添加常量单元

添加一个新的Unit,另存为“unt<工程名>”,用来保存工程中用到的常量。

四.有关窗体(Form)及单元(Unit) 

按照匈牙利命名法则给Form命名,则一个用来登录的窗体可以命名为’FrmLogin’,而其单元名可以为’untLogin’。

通常,两个对应的Form和Unit的名称在除去’Frm’或’unt’的缩写后应当保持一致。

在Unit的头部添加本单元的注释,注释的格式可以参照Delphi的源码,但是至少应当包含以下几项:

功能描述;作者;版权;创建时间;最后修改时间;修改历史等等。

将新创建好的Form的Caption设置为该Form类的名称,而不是使用Delphi默认的。

比如,将Form1更名为FrmLogin后,此时我们获得了TFrmLogin这个新的窗体类,并且Delphi自动将窗体的Caption更新为’FrmLogin’。

依我看,该Caption应当为’TFrmLogin’才是,因为我们在设计的是一个窗体类TFrmLogin,而不是仅仅对FrmLogin进行操作。

向TFrmLogin这样功能明确的窗体类,许多人都有在设计期就将其Caption设置为诸如“操作员登录”这种名称的习惯。

我的习惯是,象“操作员登录”这样的常量,通常存放在unt<工程名>中,用ResourceString来定义,或者用Const来定义。

至于窗体的Caption的命名,应当属于运行期的工作。

所以,我往往在事件触发之时才对Caption进行操作,比如:

procedure(Sender:

TObject);

begin

    Caption:

=csLoginTitle;

   ....

end;

五.关于Format函数的使用

    有iYear,iMonth,iDay三个数据,要显示诸如“生日:

1976/3/18”这样的信息,你通常怎么做使用s:

=‘生日:

’+IntToStr(iYear)+’.’+IntToStr(iMonth)+’.’+IntToStr(iDay);吗这样实在是太累了。

我的习惯是,在unt<工程名>中增加一个常量csBirthDayFormat=‘生日:

%d/%d/%d’来保存显示格式,然后使用s:

=Format(csBirthDayFormat,[iYear,iMonth,iDay]);这样的语句完成数据的拼装。

这么做的好处显而易见,那就是你只需在一个地方维护数据的显示格式。

    Format函数功能强大,我对它很是推崇,你呢

六.关于注册表或者Ini文件的存储

原先访问注册表我通常使用TRegistry,而访问Ini文件通常使用TIniFile。

这两个类的使用方法各不相同,因此想要使用相同的代码既能访问注册表又能访问Ini文件几乎是不可能的。

真头疼啊!

终于我发现了救星!

那就是TRegistryIniFile类。

查看Registry单元,我们发现,TRegistryIniFile继承自TCusomIniFile。

而TIniFile也是继承于TCusomIniFile。

因此,使用抽象类TCusomIniFile来实现对注册表或者Ini文件的访问便是一举两得了。

比如:

var

csmIniFile:

TCusomIniFile;

begin

ifblUseIniFilethen

2000-5-1}

{}

{}

{Programmer:

}

{xiaoli(China)}

{StevenLee(US)}

{}

{}

{***********************************************************}

uses子句

在interface部分的uses子句应包含在interface部分中的代码所需要的单元,去掉那些DelphiIDE可以自动加入到程序中的单元。

在implementation部分的uses子句应只包含在implementation部分中的代码所需要的单元的名字,去掉不必要的单元。

interface部分

interface部分应包含只那些其它单元所需要存取类型的定义、变量、过程或函数的预定义等等。

否则,就应放在implementation部分定义。

implementation部分

implementation部分应包含那些只在本单元中私用的类型定义、变量、过程或函数定义等等。

一些重要的单元,特别是当多人协作时,指定修改历史,将对以后的维护提供重要依据。

示例:

01:

32:

50}

{}

{}

{Programmer:

}

{xiaoli(China)}

{StevenLee(US)}

{}

{}

{***********************************************************}

00:

12:

53Mainfm}

procedure(Sender:

TObject);

begin

ShowMessage('HelloWorld');

end;

end.

01:

32:

503]ofTPoint;

数组的变量实例的名称应是其类型的名字去掉前缀T,

示例:

var

PointArray:

TPointArray;

记录类型

记录类型的名字应符合使用它们的目的,并在该类型的名字前加以前缀T。

如果要声明该记录类型的指针,就应加以前缀P并且在类型声明的前面声明。

示例:

type

PEmployee=^TEmployee;

TEmployee=record

EmployeeName:

string;

EmployeeAge:

Integer;

end;

语句

if语句

在if…then…else语句中最常发生的行为应放在if…then子句内,而其它发生可能性较小的行为应放在else子句中。

尽量避免使用嵌套的if语句,在这种情形下应使用多个if语句来判断各种可能。

如果if嵌套超过五级深度,应更换算法应使代码编写得更加清晰、明了。

示例:

{不推荐的写法,嵌套的判断条件,将降低程序的可读性}

ifiCounter=0then

begin

K:

=0;

end

elsebegin

ifiCounter=1begin

begin

K:

=1;

end

elsebegin

ifiCounter=2then

begin

k:

=2;

end;

end

end;

{推荐的写法,程序可读性强}

ifiCounter=0then

begin

K:

=0;

end;

ifiCounter=1then

begin

K:

=1;

end;

ifiCounter=2then

begin

K:

=2;

end;

不要在if语句中使用不必要的圆括号。

示例:

if(iCounter=0)thenext+',';

end;

repeat语句

repeat语句的使用同while语句一样。

with语句

with语句遵循本文档所说明的命名约定和缩格的格式规则。

with语句应节省使用,避免过度使用with语句并且在with语句中小心使用多个对象、记录等等,这往往使程序员感到困惑并难以发现问题所在。

示例:

withQuery1,ListBox1do

begin

DoSomething();

end;

异常处理

try…finally的使用

尽可能地在每一次的资源或对象分配都跟随一个try…finally,特别是当创建资源时没有Owner的情况下。

下面的代码可能会造成资源泄漏,

示例:

SomeObj1:

=;

SomeObj2:

=;

try

DoSomething;

finally

;

;

end;

相对地,一个比较安全的对象分配过程如下:

示例:

SomeObj1:

=;

try

SomeObj2:

=;

try

DoSomething;

finally

;

end;

finally

;

end;

try…except的使用

当在异常被触发而想在异常发生时执行一些任务时才使用try…except。

因此,通常没有必要为了只是简单地在屏幕上显示一个错误信息而使用try…except语句,因为这会被Application全局对象自动执行。

如果想在except子句中执行完一些任务之后调用缺省的异常处理,使用raise来重新触发异常到下一个句柄。

try…except…else的使用

try…except中的else子句不建议使用,因为它会打断所有的异常包括那些没有准备的异常。

命名和格式

类的名称应符合使用它们的目的,类型名字应加以前缀T以表明这是一个类型的定义。

示例:

type

TCustomer=class(TObject)

private

FName:

string;

public

functionGetName:

string;

end;

var

Customer:

TCustomer;

begin

DoSomething;

end;

私有变量(private)

类的私有变量名遵循与变量标识符同样的约定,除了它们应以F为前缀来表明这是一个私有变量的名称,如示例。

想在类的范围之外存取私有变量必须通过属性来访问。

方法

命名

方法的命名应遵循本文档中有关过程和函数的约定叙述。

使用静态方法

如果使用一个静态的方法,那么说明不打算让该类的子类继承,应放置在private内。

示例:

type

TCustomer=class(TObject)

private

FName:

string;

functionGetName:

string;

protected

functionGetCustomerInfo:

string;virtual;

public

procedureSearchCustomerInfo(constName:

string);

published

propertyCustomerNamereadGetNamewriteFName;

end;

使用虚拟(virtual)或动态(dynamic)方法

如果打算让该类的方法能被子类继承就要使用虚拟或动态方法。

只有在该方法有多个继承时(直接的或间接的)才使用动态方法(dynamic)。

例如,一个类包含一个可继承的方法,而100个子类要继承这种方法,那么这个方法就会动态地产生为100个子类使用的内存。

使用抽象方法(abstract)

如果在一个类中使用抽象的方法,该类就不能被创建。

只有在那些永远不会被创建的类中使用抽象方法(abstract)。

属性存取方法

所有存取属性的方法都只能出现在类的private或protected部分。

属性存取方法的命名应遵循过程和函数的约定规则,读取存取方法以单词Get为前缀,写入方法以单词Set为前缀。

存取方法参数的名字应为Value,并且它的类型应是它所操作的属性的类型。

示例:

TSomeClass=class(TObject)

private

FSomeField:

Integer;

protected

functionGetSomeField:

Integer;

procedureSetSomeField(Value:

Integer);

public

propertySomeField:

IntegerreadGetSomeFieldwriteSetSomeField;

end;

属性

属性如果是表示为一个私有域的访问接口的话,那么它的名字应是它们所操作的域的名字除去前缀F。

属性的名字应是名词,不是动词。

属性表示的是数据,而方法表示的是行为。

数组类型的名称应为复数,一般情况下属性的名称应为单数。

注释

任何没有注释代码的程序是令人生畏的,新接手的程序员往往需要通读所有的代码,并做大量的测试实验才有可能理解原作者的意图。

因此,如何编写规范的注释是非常重要的内容。

一个好的程序员的代码应该是容易维护的,能够使人很快明白代码的意图,使用隐晦、非常规的代码编写手法的程序员并不一定是好的程序员。

在Delphi程序中,有三种注释方法:

{……}、//……、(*……*)。

只推荐使用{……}注释Delphi代码,//……只允许少量地使用在代码级别的注释。

推荐一种注释方法,

示例

{10获取销售日期}

SaleMonth:

=Date();

{20准备本月所有人员的销售明细}

{清空本月的旧数据}

try

:

=crHourGlass;

:

='正在清空当月的旧数据';

sSQL:

='DELETEFROMsellers'

+'WHEREsale_month=#'+DateToStr(SaleMonth)+'#';

(sSQL,True);

:

='正在准备当月空白业务员业绩清单';

{列空白清单:

有编号业务员}

(sSQL,True);

{列空白清单:

生成新业务员空白业绩清单}

(sSQL,True);

{30根据销售日期计算当月员工薪资}

sSQL:

='SELECTbuyer_id'

以上是一个代码片段,通过阅读注释,可轻松理解该段代码的含义,需要注意的是该段代码以序号分割各个逻辑功能,如:

10,20,30。

在某个大的逻辑下,再细分功能步骤,如:

,,,这样阅读程序可根据情况选择通读或精读,这样做另一个好处是,添加或修改代码,可进行注释的同步更新。

示例

{10播放结束动画}

ProgEnd:

=False;

:

=_EndMovie;

whileand(notProgEnd)do

begin

;

end;

;

;//清理工作,非常重要

{20还原全屏}

SetDisplayMode(False);

以加了序号的{……}注释风格来注释程序的逻辑功能,少量使用//……注释代码来提醒程序员某些代码的重要作用。

4组件命名约定

除以上代码风格规范外,在设计时统一组件的命名也非常重要。

一般情况下,提取组件的三个字母作为该组件的前缀(小写),再加一个描述性的名字作为该组件的名字。

这不仅是为了在对象检查器和代码浏览器中搜寻组件的名字时更容易,更重要的是我们不必通过反复核查代码和窗体上具体的组件名就知道我们现在用的是哪个组件。

以下是组件前缀的参考命名(Delphi4):

Standard页

mmTMainMenu

pmTPopupMenu

mmiTMainMenuItem

pmiTPopupMenuItem

lblTLabel

edtTEdit

memTMemo

btnTButton

cbTCheckBox

rbTRadioBox

lbTListBox

cbTComboBox

scbTScrollBar

gbTGroupBox

rgTRadioGroup

pnlTPanel

clTCommandList

Additional页

bbtnTBitBtn

sbTSpeedButton

meTMaskEdit

sgTStringGrid

dgTDrawGrid

imgTImage

shpTShape

bvlTBevel

sbxTScrollBox

clbTCheckListbox

splTSplitter

stxTStaticText

chtTChart

Win32页

tbcTTabControl

pgcTPageControl

ilTImageList

reTRichEdit

thrTTrackBar

prbTProgressBar

udTUpDown

hkTHotKey

aniTAnimate

dtpTDateTimePicker

tvTTreeView

lvTListView

hdrTHeaderControl

stbTStatusBar

tlbTToolBar

clbTCoolBar

System页

tmTTimer

pbTPaintBox

mpTMediaPlayer

olecTOleContainer

ddccTDDEClientItem

ddciTDDEClientItem

ddscTDDEServerConv

ddsiTDDEServerItem

Internet页

cskTClientSocket

sskTServerSocket

wbdTWebDispatcher

ppTPageProducer

tpTQueryTableProducer

dstpTDataSetTableProducer

nmdtTNMDayTime

necTNMEcho

nfTNMFinger

nftpTNMFtp

nhttpTNMHttp

nMsgTNMMsg

nmsgTNMMSGServ

nntpTNMNNTP

npopTNMPop3

nuupTNMUUProcessor

smtpTNMSMTP

nstTNMStrm

nstsTNMStrmServ

ntmTNMTime

nudpTNMUdp

pskTPowerSock

ngsTNMGeneralServer

htmlTHtml

urlTNMUrl

smlTSimpleMail

DataAccess页

dsTDataSource

tblTTable

qryTQuery

spTStoredProc

dbTDataBase

ssnTSession

bmTBatchMove

usqlTUpdateSQL

DataControls页

dbgTDBGrid

dbnTDBNavigator

dbtTDBText

dbeTDBEdit

dbmTDBMemo

dbiTDBImage

dblbTDBListBox

dbcbTDBComboBox

dbchTDBCheckBox

dbrgTDBRadioGroup

dbllTDBLookupListBox

dblcTDBLookupComboBox

dbreTDBRichEdit

dbcgTDBCtrlGrid

dbchTDBChart

DecisionCube页

dcbTDecisionCube

dcqTDecisionQuery

dcsTDecisionSource

dcpTDecisionPivot

dcgTDecisionGrid

dcgrTDecisionGraph

QReport页

qrTQuickReport

qrsdTQRSubDetail

qrbTQRBand

qrcbTQRChildBand

qrgTQRGroup

qrlTQRLabel

qrtTQRText

qreTQRExpr

qrsTQRSysData

qrmTQRMemo

qrrtTQRRichText

qrdrTQRDBRichText

qrshTQRShape

qriTQRImage

qrdiTQRDBMImage

qrcrTQRCompositeReport

qrpTQRPreview

qrchTQRChart

Dialogs页

OpenDialogTOpenDialog

SaveDialogTSaveDialog

OpenPictureDialogTOpenPictureDialog

SavePictureDialogTSavePictureDialog

FontDialogTFontDialog

ColorDialogTColorDialog

PrintSetupDialogTPrintSetupDialog

FindDialogTFindDialog

ReplaceDialogTReplaceDialog

dbllTDBLookupList

dblcTDBLookupCombo

tsTTabSet

olTOutline

tnbTTabbedNoteBook

nbTNoteBook

hdrTHeader

flbTFileListBox

dlbTDirectoryListBox

dcbTDriveComboBox

fcbTFliterComboBox

Samples页

ggTGauge

cgTColorGrid

spbTSpinEdit

speTSpinEdit

dolTDirectoryOutline

calTCalendar

ibeaTIBEventAlerter

ActiveX页

cfxTChartFX

vspTVSSpell

f1bTF1Bo

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 高等教育 > 军事

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1