【转】高质量编程规范 编写:谢先博 语言:VB 版
高质量编程规范
编写:谢先博
语言:VB
版本:Ver 1.0
2006-4-20
前言.................................................................................................................................................3
第一章程序的版式......................................................................................................................3
1.1代码格式化目的..............................................................................................................3
1.2 代码格式约定.................................................................................................................3
第二章命令规则............................................................................................................................6
2.1 控件命名.........................................................................................................................6
2.2 变量命名.........................................................................................................................7
2.3 常量命名约定.................................................................................................................9
2.4 函数命名约定.................................................................................................................9
第三章表达式和基本语句........................................................................................................10
3.1 复合表达式...................................................................................................................10
3.2 循环语句的效率...........................................................................................................10
3.3 错误处理....................................................................................................................... 11
第四章优化与性能调节..............................................................................................................12
第五章用户界面设计规范..........................................................................................................16
5.1 界面设计原则...............................................................................................................16
5.2 界面设计基础...............................................................................................................16
第六章小组开发规范................................................................................................................17
前言
编程规范的目的:编写编程规范的主要原因,是使应用程序的结构和编码风格标准化,
以便于阅读和理解这段编码,同时也会使代码更健壮。在现代软件开发中,维护工作会占用
80%的时间,而且开发者和维护者通常不是一个程序员。这意味着你经常要阅读和修改别
人开发的程序,同样地别人也可能需要阅读和修改你的程序。
好的编码规范可使源代码严谨、可读性强且意义清楚,与其他语言约定相一致,并且尽
可能的直观。统一标准的好处在育能团结一群人按照相同的习惯去工作。
编程规范的目的是使程序易于阅读和理解,易于维护,而不是用过分的约束和绝对的限
制来束缚程序员本身的创造性。标准使人定的,它并不是神圣不可侵犯的。所以编写的规范
是简洁和建议性的。而且它的规范需要我们在实际工作当中继续修改直到完善。
第一章 程序的版式
1.1代码格式化目的
对代码进行格式化时,所要达到的目的:
·通过将代码分隔成功能块和便于理解的代码段,使代码更容易阅读和理解。
·减少为理解代码结构而需要做的工作。
·使代码的阅读者不必进行假设。
·使代码结构尽可能做到格式清楚明了。
1.2 代码格式约定
【规则1】在每个函数定义之后都要加空行
例如:
风格良好的代码行不良风格的代码行
Private width As Integer
Private Height As Integer
Private Width as Integer, Height
as Integer
【规则2】使用空白行将相关的语句组织起来
在以下情况,要插入空白行:
·每个If……Then 构造的前面和后面(尤其是If语句前的注释的前面)
·每个Select Case构造的前面
·每个循环的前面和后面
·变量块的说明的后面
·执行统一任务的两个语句组的中间
·应该在两个过程或函数之间插入两个空行
【规则3】一行代码只做一件事情。
当多个语句出现在同一个代码行上,各个语句之间用冒号分开时,很难确定一个语
句在何处结束而另一语句在何处开始,这无形之中就增加了代码的复杂性。
例如:
风格良好的代码行不良风格的代码行
x=t
t=y
y=x
x=t:t=y:y=x
【规则4】当产生长字符串时,使用下划线连接字符拆分成多行代码,这样便于阅读或调试
字符串。当显示一个消息框(MsgBox) 或输入框(InputBox),或产生一个SQL 字符串
时,这一技术特别有用。拆分出的新行要进行适当的缩进,使排版整齐,语句可读。
例如:
Dim Msg As String
Msg = "This is a paragraph that will be " _
& "in a message box. The text is" _
& " broken into several lines of code" _
& " in the source code, making it easier" _
& " for the programmer to read and debug."
MsgBox Msg
Dim QRY As String
QRY = "SELECT *" _
& " FROM Titles" _
& " WHERE [Year Published] > 1988"
TitlesQry.SQL = QRY
【规则5】VB的注释符号为Rem 和’ 。我们通常采用“’”。注释通常用于:
(1)版本、版权声明;
(2)函数接口说明;
(3)重要的代码行或段落提示
虽然注释有助于理解代码,但注意不可过多地使用注释。
注释是对代码的“提示”,而不是文档。程序中的注释不可喧宾夺主,注释太多了会让眼花
缭乱。如果代码本来就很清楚,则不必加注释。
例如:
i=i+1 ‘i 加1
这样的注释就不需要添加。
【规则6】函数接口说明格式
‘函数说明:
‘输入参数:
‘输出参数:
‘返回值:
【规则7】代码缩进
缩进代码行后,阅读代码的人就能直观地了解执行统一任务的各个语句的组织结构。
当遇到以下情况时,代码要缩进一个TAB制表位(这里一个制表位为4个字符):
·当使用End If时,在If语句后缩进。
例如: if Prow =nothing Then
Exit Feunction
End If
·在Else语句后缩进
例如: if Fieldindex =-1 Then
GetFieldValue=”Null”
Else
Dim pValue As Variant
pValue=pRow.Value(fieldIndex)
GetFieldValue=Iif(IsNull(pValue),”Null”,pValue)
End If
·在Select Case 语句后缩进
·在Csse语句后缩进
·在Do 语句后缩进
·已经用行接续符分隔的语句的各个行要缩进
·在With 语句后缩进
·在调用Recordset 对象的Edit 和AddNew 方法后缩进。Update 或
ConcelUpdate方法的缩进层次应该与Edit或AddNew 语句相同。
·在调用BeginTrans方法后缩进
·对模块的Declarations 部分中的代码进行缩进,显示其从属关系。
·对所有枚举说明的主体进行缩进。
第二章命令规则
2.1 控件命名
【规则1】控件命名规则见下表
控件类型 前缀 例子
3D Panel pnl pnlGroup
ADO Data ado adoBiblio
Animated button ani aniMailBox
Check box chk chkReadOnly
Combo box cbo cboEnglish
Command button cmd cmdExit
Common dialog dlg dlgFileOpen
Communications com comFax
Control ctr ctrCurrent
Date picker dtp dtpPublished
Data dat datBiblio
Data-bound combo box dbcbo dbcboLanguage
Data-bound grid dbgrd dbgrdQueryResult
Data-bound list box dblst dblstJobType
Data combo dbc dbcAuthor
DataGrid dgd dgdTitles
Data list dbl dblPublisher
Data repeater drp drpLocation
Directory list box dir dirSource
Drive list box drv drvTarget
File list box fil filSource
Flat scroll bar fsb fsbMove
Form frm frmEntry
Frame fra fraLanguage
Gauge gau gauStatus
Graph gra graRevenue
Grid grd grdPrices
Hierarchical flexgrid flex flexOrders
Horizontal scroll bar hsb hsbVolume
Image img imgIcon
Image combo imgcbo imgcboProduct
ImageList ils ilsAllIcons
Label lbl lblHelpMessage
Lightweight check box lwchk lwchkArchive
Lightweight combo box lwcbo lwcboGerman
Lightweight command
button
lwcmd lwcmdRemove
Lightweight frame lwfra lwfraSaveOptions
Lightweight horizontal
scroll bar
lwhsb lwhsbVolume
Lightweight list box lwlst lwlstCostCenters
Lightweight option button lwopt lwoptIncomeLevel
Lightweight text box lwtxt lwtxtStreet
Lightweight vertical
scroll bar
lwvsb lwvsbYear
Line lin linVertical
List box lst lstPolicyCodes
ListView lvw lvwHeadings
MAPI message mpm mpmSentMessage
MAPI session mps mpsSession
MCI mci mciVideo
Menu mnu mnuFileOpen
Month view mvw mvwPeriod
MS Chart ch chSalesbyRegion
MS Flex grid msg msgClients
MS Tab mst mstFirst
OLE container ole oleWorksheet
Option button opt optGender
Picture box pic picVGA
Picture clip clp clpToolbar
ProgressBar prg prgLoadFile
Remote Data rd rdTitles
RichTextBox rtf rtfReport
Shape shp shpCircle
Slider sld sldScale
Spin spn spnPages
StatusBar sta staDateTime
SysInfo sys sysMonitor
TabStrip tab tabOptions
Text box txt txtLastName
Timer tmr tmrAlarm
Toolbar tlb tlbActions
TreeView tre treOrganization
UpDown upd updDirection
Vertical scroll bar vsb vsbRate
2.2 变量命名
【规则2】变量应该总是被定义在尽可能小的范围内。
在Visual Basic中变量可以有下列范围:
范围声明位置 声明 变量范围
过程级过程Private 声明过程中
模块级窗体
代码模块
Private 声明的窗体、模块中
全局 标准模块Public 整个工程
【规则3】尽可能减少使用全局变量。全局(Public) 变量可以导致极其复杂的状态机构,
并且使一个应用程序的逻辑非常难于理解,使代码的重用和维护更加困难。在应用程序中,
只有当没有其它方便途径在窗体之间共享数据时才使用全局变量。
【规则4】当必须使用全局变量时,在一个单一模块中声明它们,并按功能分组。给这个模
块取一个有意义的名称,以指明它的作用。
【规则5】全局变量命令规则:g+名称
模块级变量命令规则:p+名称
范围 前缀 例子
全局 g gstrUserName
模块级p pblnCalcInProgress
本地到过程无 dblVelocity
【规则6】局部变量的命令规则:数据类型缩写+ 名字
数据类型 前缀 例子
Boolean bln blnFound
Byte byt bytRasterData
Collection col colWidgets
Currency cur curRevenue
Double dbl dblTolerance
Error err errOrderNum
Integer int intQuantity
Long lng lngDistance
Object obj objCurrent
Single sng sngAverage
String str strFName
User-def udt udtEmployee
Variant vnt vntCheckSum
【规则8】静态变量加前缀st(表示static)。
例如:
static stinitValue as integer ‘ 静态变量
【规则9】类的数据成员加前缀m(表示member),这样可以避免数据成员与成员函数的
参数同名。
例如:
Public Type student
mnum As String * 8
mname As String * 8
mtotal As String * 8
maverage As Integer
End Type
2.3 常量命名约定
常量与变量不同,它是在设计代码时被赋予值的,这个值不能在运行时更改,使用常
量可以代替硬编码,而且使代码更容易阅读,变得比较直观明了。
常量名建议最好全部大写,使用下划线作为单词间的分隔符,单词尽量使用全名称。
【规则10】常量全用大写的字母,用下划线分割单词
例如:
const MAX = 100
const MAX_LENGTH = 100
【规则11】使用Option Explicit语句要求在Visual Basic 程序中声明所有的变量。
2.4 函数命名约定
此处函数包括Sub和Function,以下将这两个过程统称为函数。
函数表示的是一个动作,所以它的结构应该是动词+名词,动词必须小写,后面的名称首字
母大写,
例如:setWorkspaceEditState
loadDianLanData
setFieldValue
【规则12】函数命令尽量不要使用缩写,而且它的名称应该使人一目了然,必须能够反映
函数的作用,能够从名称就知道这个函数的功能。
【规则13】函数命名必须能准确表达所要实现的功能,不至于引起歧义。
第三章表达式和基本语句
3.1 复合表达式
【规则1】如果代码行中的运算符比较多,用括号确定表达式的操作顺序,避免使用默认的
优先级。
例如: if a>b & a<c
【规则2】不要编写太复杂的复合表达式
例如:i=a>=b &c<d &c+f<=g+h ‘复合表达式过于复杂
【规则3】不可将布尔变量直接与True、False或者1、0进行比较
根据布尔类型的定义,零值为假(记为False),任何非零值都是“真”(记为True)。
True的值究竟是什么并没有统一的标准。
假设布尔变量名字为flag,它与零值比较的标准if 语句如下:
if flag then ‘表示flag 为真
if !flag then ‘表示flag 为假
其他的用法都属于不良风格:
例如:
if flag=True then
if flag=1 then
if flag=false then
【规则4】应当将整型变量用“==”或“!=”直接与0比较。
假设整型变量的名字为Value,它与零值比较的标准if语句如下:
if Value=0 then
if Value <>0 then
3.2 循环语句的效率
For语句使用效率最高,While语句其次,Do语句很少用。本节重点论述循环体的效率。
提高循环体效率的基本办法是降低循环体的复杂性。
【规则5】在程序中尽量避免使用循环,可以用其他方式完成尽量使用其他方式。
【规则6】在多重循环中,如果有可能,应当将最长的循环放在最内层,最短的循环放在最
外层,以减少CPU跨切循环层的次数。
For row=0 to 100
For col=0 to 5
Sum=Sum+a
Next col
Next row
For col=0 to 5
For row=0 to 100
Sum=Sum+a
Next row
Next col
低效率:长循环在最外层高效率:长循环在最内层
【规则7】如果循环体内存在逻辑判断,并且循环次数很大,宜将逻辑判断移到循环体的外
面。
For i=0 to N
If condition then
Dosomething()
Else
Dosomething()
Endif
Next i
If condition then
For i=0 to N
Dosomething()
Next i
Else
For i=0 to N
Dosomething()
Next i
Endif
效率低但程序更简洁效率高但程序不简洁
【规则8】不可在For循环体内修改循环变量,防止For循环失去控制。
【规则9】switch 是多分支选择语句,而If语句只有两个分支可供选择,虽然可以用If语句
的嵌套方式来实现多分支选择,但这样的程序冗长难懂,这时选用Switch较为方便。
3.3 错误处理
运用错误处理程序要达到的目的时:
·防止你的程序崩溃
·可能时恰当地纠正错误
·发生错误时将情况通知用户,以便纠正错误。
【规则10】使用On Error Resume Next以忽略错误
对错误进行处理地最简单同时也是最危险地方法是使用On Error Resume Next语句。
On Error Resume Next语句规定,代码中地错误将完全被忽略,存在错误的代码行被跳
过,然后继续执行下一个语句。
【规则11】使用On Error GoTo转移执行的代码流
转移执行的代码用行标注来指定,行标注是一个文本串,用于标识一个单行代码。行标
注可以是任何字符的组合,它以一个字母开始,以冒号(:)结尾。
第四章优化与性能调节
【规则1】使用正确的数据类型
提高代码运行速度最简单的方法莫过于使用正确的数据类型了。也许你不相信,但是
正确地选择数据类型可以大幅度提升代码的性能。在大多数情况下,程序员可以将Single,
Double和Currency类型的变量替换为Integer或Long类型的变量,因为VB处理Integer
和Long的能力远远高于处理其它几种数据类型。
在大多数情况下,程序员选择使用Single或Double的原因是因为它们能够保存小
数。但是小数也可以保存在Integer类型的变量中。例如程序中约定有三位小数,那么只需
要将保存在Integer变量中的数值除以1000就可以得到结果。根据我的经验,使用Integer
和Long替代Single,Double和Currency后,代码的运行速度可以提高将近10倍。
【规则2】避免使用变体
对于一个VB程序员来说,这是再明显不过的事情了。变体类型的变量需要16个字节
的空间来保存数据,而一个整数(Integer)只需要2个字节。通常使用变体类型的目的是
为了减少设计的工作量和代码量,也有的程序员图个省事而使用它。但是如果一个软件经过
了严格设计和按照规范编码的话,完全可以避免使用变体类型。
在这里顺带提一句,对于Object对象也存在同样的问题。请看下面的代码:
Dim FSO
Set FSO = New Scripting.FileSystemObject
或
Dim FSO as object
Set FSO = New Scripting.FileSystemObject
上面的代码由于在申明的时候没有指定数据类型,在赋值时将浪费内存和CPU时间。正
确的代码应该象下面这样:
Dim FSO as New FileSystemObject
【规则3】尽量避免使用属性
在平时的代码中,最常见的比较低效的代码就是在可以使用变量的情况下,反复使用
属性(Property),尤其是在循环中。要知道存取变量的速度是存取属性的速度的20倍左右。
下面这段代码是很多程序员在程序中会使用到的:
Dim intCon as Integer
For intCon = 0 to Ubound(SomVar())
Text1.Text = Text1.Text & vbcrlf & SomeVar(intCon)
Next intCon
下面这段代码的执行速度是上面代码的20倍。
Dim intCon as Integer
Dim sOutput as String
For intCon = 0 to Ubound(SomeVar())
sOutput = sOutput & vbCrlf &
SomeVar(intCon)
Next
Text1.Text = sOutput
【规则4】尽量使用数组,避免使用集合
除非你必须使用集合(Collection),否则你应该尽量使用数组。据测试,数组的存
取速度可以达到集合的100倍。这个数字听起来有点骇人听闻,但是如果你考虑到集合是一
个对象,你就会明白为什么差异会这么大。
【规则5】避免使用很短的函数
和使用小的循环体相同,调用只有几行代码的函数也是不经济的--调用函数所花费的
时间或许比执行函数中的代码需要更长的时间。在这种情况下,你可以把函数中的代码拷贝
到原来调用函数的地方。
【规则6】减少对子对象的引用
在VB中,通过使用.来实现对象的引用。
例如:
Form1.Text1.Text
在上面的例子中,程序引用了两个对象:Form1和Text1。利用这种方法引用效率很
低。但遗憾的是,没有办法可以避免它。程序员唯一可以做就是使用With或者将用另一个
对象保存子对象(Text1)。
' 使用With
With frmMain.Text1
.Text = "Learn VB"
.Alignment = 0
.Tag = "Its my life"
.BackColor = vbBlack
.ForeColor = vbWhite
End With
【规则7】检查字符串是否为空
大多数程序员在检查字符串是否为空时会使用下面的方法:
If Text1.Text = "" then
' 执行操作
End if
很不幸,进行字符串比较需要的处理量甚至比读取属性还要大。因此我建议大家使用
下面的方法:
If Len(Text1.Text) = 0 then
' 执行操作
End if
【规则8】使用数组,而不是多个变量
当你有多个保存类似数据的变量时,可以考虑将他们用一个数组代替。在VB中,数组
是最高效的数据结构之一。
【规则9】使用动态数组,而不是静态数组
使用动态数组对代码的执行速度不会产生太大的影响,但是在某些情况下可以节约大
量的资源。
【规则10】销毁对象
无论编写的是什么软件,程序员都需要考虑在用户决定终止软件运行后释放软件占用
的内存空间。但遗憾的是很多程序员对这一点好像并不是很在意。正确的做法是在退出程序
前需要销毁程序中使用的对象。
例如:
Dim FSO as New FileSystemObject
' 执行操作
' 销毁对象
Set FSO = Nothing
对于窗体,可以进行卸载:
Unload frmMain
或
Set frmMain = Nothing
【规则11】变长和定长字符串
从技术上来说,与变长字符串相比,定长字符串需要较少的处理时间和空间。但是
定长字符串的缺点在于在很多情况下,你都需要调用Trim函数以去除字符串末的空字符,
这样反而会降低代码效率。所以除非是字符串的长度不会变化,否则还是使用变长字符串。
【规则12】使用内部对象
在涉及到使用ActiveX控件和DLL的时候,很多程序员喜欢将它们编译好,然后再加入
工程中。我建议你最好不要这样做,因为从VB连接到一个外部对象需要耗费大量的CPU处
理能力。每当你调用方法或存取属性的时候,都会浪费大量的系统资源。如果你有ActiveX
控件或DLL的源代码,将它们作为工程的私有对象。
【规则13】减少模块的数量
有些人喜欢将通用的函数保存在模块中,对于这一点我表示赞同。但是在一个模块中只
写上二三十行代码就有些可笑了。如果你不是非常需要模块,尽量不要使用它。这样做的原
因是因为只有在模块中的函数或变量被调用时,VB才将模块加载到内存中;当VB应用程序
退出时,才会从内存中卸载这些模块。如果代码中只有一个模块,VB就只会进行一次加载
操作,这样代码的效率就得到了提高;反之如果代码中有多个模块,VB会进行多次加载操
作,代码的效率会降低。
【规则14】使用对象数组
当设计用户界面时,对于同样类型的控件,程序员应该尽量使用对象数组。你可以做
一个实验:在窗口上添加100个PictureBox,每个PictureBox都有不同的名称,运行程序。
然后创建一个新的工程,同样在窗口上添加100个PictureBox,不过这一次使用对象数组,
运行程序,你可以注意到两个程序加载时间上的差别。
【规则15】使用Move方法
在改变对象的位置时,有些程序员喜欢使用Width,Height,Top和Left属性。例如:
Image1.Width = 100
Image1.Height = 100
Image1.Top = 0
Image1.Left = 0
实际上这样做效率很低,因为程序修改了四个属性,而且每次修改之后,窗口都会被重
绘。正确的做法是使用Move方法:
Image1.Move 0,0,100,100
【规则16】减少图片的使用
图片将占用大量内存,而且处理图片也需要占用很多CPU资源。在软件中,如果可能的
话,可以考虑用背景色来替代图片--当然这只是从技术人员的角度出发看这个问题。
【规则17】使用类模块,而不是ActiveX控件除非ActiveX控件涉及到用户界面,否则尽量
使用轻量的对象,例如类。这两者之间的效率有很大差异。同样的尽量使用ActiveX dll。
【规则18】ListView控件与DataGrid控件的选取。当涉及显示的数据库记录较少时可以选
择ListView控件显示,而当显示记录条数较多时使用DataGrid控件显示。
第五章用户界面设计规范
5.1 界面设计原则
·用户界面设计必须保持一致,界面设计的一致性要达到的目的是:
·创建程序中统一的界面,并且创建不通应用程序中的统一的界面;
·使得用户能够充分利用他们现有的技巧;
·减少用户在操作中的混乱和困难
·形成醒目的界面,建立用户的信息,使得用户感到满意;
·用简明扼要的专业性语言高司用户他们必须知道的消息。
5.2 界面设计基础
【规则1】在规定情况喜爱使用最佳界面组件
·如果TextBox控件仅用于显示数据,可以换成Label控件
·使用滚动条ScrollBar来指明数量和速度
·只有在绝对必要时才选用Picture控件,建议使用Image控件来显示图片
·当允许用户选定和取消选项项目时,应尽量采用复选框CheckBox
·使用列表框ListBox显示带有5个以上项目的动态列表和静态列表
·若运行一段程序需要长时间的等待,使用进度条ProgressBar可以缓和用户的紧张。
【规则2】精心设置所有窗体的Tab键顺序。
【规则3】创建对话框中的默认命令按钮和Cancel(取消)命令按钮。
【规则4】设置与数据域相关联的控件的MaxLength属性。数据库表格中的大多数字段都
有一个它们能够存放的最大字符数。如果试图将超出允许范围的字符数目村翻盖数据表中将
会引起错误。
【规则5】创建功能良好的消息框
信息类消息框(vbInformation)提示比较简单的非危急状况的通知信息。
警告类消息框(vbExclamation)用于将一些非常重要的消息通知用户。
问号图标(vbQuestion)应该用于向用户提出问题的消息框。给用户一个自己选择
的机会。
危急状况消息框(vbCritical)用于将某些绝对必须注意的情况通知用户。
第六章小组开发规范
【规则1】每次对程序编译后应将版本号递增1
编译一个程序或ActiveX组件时,编译文件中就包含一个版本号。这个版本号供安装
程序用于确保文件不会被较老的文件版本改写。若要查看文件的版本号,可以使用Windows
Explorer,查看文件的属性,它能够比较容易地查找安装错误。
版本号的格式通常如下所示:
主.次.修改号
当显示版本信息时,请记住次版本号通常显示为右对齐的4个数字。例如,若要显示
3.1版的第27次修改程序,该版本号应该时下面的形式:
3.1.0027
【规则2】使用Vss来维护源代码的版本
对于复杂的项目,应该考虑使用Visual SouceSafe来管理项目。Visual SouceSafe
能够跟踪项目中所有文件的所有修改版本,使你能在必要时很容易转到某个版本。
编写:谢先博
语言:VB
版本:Ver 1.0
2006-4-20
前言.................................................................................................................................................3
第一章程序的版式......................................................................................................................3
1.1代码格式化目的..............................................................................................................3
1.2 代码格式约定.................................................................................................................3
第二章命令规则............................................................................................................................6
2.1 控件命名.........................................................................................................................6
2.2 变量命名.........................................................................................................................7
2.3 常量命名约定.................................................................................................................9
2.4 函数命名约定.................................................................................................................9
第三章表达式和基本语句........................................................................................................10
3.1 复合表达式...................................................................................................................10
3.2 循环语句的效率...........................................................................................................10
3.3 错误处理....................................................................................................................... 11
第四章优化与性能调节..............................................................................................................12
第五章用户界面设计规范..........................................................................................................16
5.1 界面设计原则...............................................................................................................16
5.2 界面设计基础...............................................................................................................16
第六章小组开发规范................................................................................................................17
前言
编程规范的目的:编写编程规范的主要原因,是使应用程序的结构和编码风格标准化,
以便于阅读和理解这段编码,同时也会使代码更健壮。在现代软件开发中,维护工作会占用
80%的时间,而且开发者和维护者通常不是一个程序员。这意味着你经常要阅读和修改别
人开发的程序,同样地别人也可能需要阅读和修改你的程序。
好的编码规范可使源代码严谨、可读性强且意义清楚,与其他语言约定相一致,并且尽
可能的直观。统一标准的好处在育能团结一群人按照相同的习惯去工作。
编程规范的目的是使程序易于阅读和理解,易于维护,而不是用过分的约束和绝对的限
制来束缚程序员本身的创造性。标准使人定的,它并不是神圣不可侵犯的。所以编写的规范
是简洁和建议性的。而且它的规范需要我们在实际工作当中继续修改直到完善。
第一章 程序的版式
1.1代码格式化目的
对代码进行格式化时,所要达到的目的:
·通过将代码分隔成功能块和便于理解的代码段,使代码更容易阅读和理解。
·减少为理解代码结构而需要做的工作。
·使代码的阅读者不必进行假设。
·使代码结构尽可能做到格式清楚明了。
1.2 代码格式约定
【规则1】在每个函数定义之后都要加空行
例如:
风格良好的代码行不良风格的代码行
Private width As Integer
Private Height As Integer
Private Width as Integer, Height
as Integer
【规则2】使用空白行将相关的语句组织起来
在以下情况,要插入空白行:
·每个If……Then 构造的前面和后面(尤其是If语句前的注释的前面)
·每个Select Case构造的前面
·每个循环的前面和后面
·变量块的说明的后面
·执行统一任务的两个语句组的中间
·应该在两个过程或函数之间插入两个空行
【规则3】一行代码只做一件事情。
当多个语句出现在同一个代码行上,各个语句之间用冒号分开时,很难确定一个语
句在何处结束而另一语句在何处开始,这无形之中就增加了代码的复杂性。
例如:
风格良好的代码行不良风格的代码行
x=t
t=y
y=x
x=t:t=y:y=x
【规则4】当产生长字符串时,使用下划线连接字符拆分成多行代码,这样便于阅读或调试
字符串。当显示一个消息框(MsgBox) 或输入框(InputBox),或产生一个SQL 字符串
时,这一技术特别有用。拆分出的新行要进行适当的缩进,使排版整齐,语句可读。
例如:
Dim Msg As String
Msg = "This is a paragraph that will be " _
& "in a message box. The text is" _
& " broken into several lines of code" _
& " in the source code, making it easier" _
& " for the programmer to read and debug."
MsgBox Msg
Dim QRY As String
QRY = "SELECT *" _
& " FROM Titles" _
& " WHERE [Year Published] > 1988"
TitlesQry.SQL = QRY
【规则5】VB的注释符号为Rem 和’ 。我们通常采用“’”。注释通常用于:
(1)版本、版权声明;
(2)函数接口说明;
(3)重要的代码行或段落提示
虽然注释有助于理解代码,但注意不可过多地使用注释。
注释是对代码的“提示”,而不是文档。程序中的注释不可喧宾夺主,注释太多了会让眼花
缭乱。如果代码本来就很清楚,则不必加注释。
例如:
i=i+1 ‘i 加1
这样的注释就不需要添加。
【规则6】函数接口说明格式
‘函数说明:
‘输入参数:
‘输出参数:
‘返回值:
【规则7】代码缩进
缩进代码行后,阅读代码的人就能直观地了解执行统一任务的各个语句的组织结构。
当遇到以下情况时,代码要缩进一个TAB制表位(这里一个制表位为4个字符):
·当使用End If时,在If语句后缩进。
例如: if Prow =nothing Then
Exit Feunction
End If
·在Else语句后缩进
例如: if Fieldindex =-1 Then
GetFieldValue=”Null”
Else
Dim pValue As Variant
pValue=pRow.Value(fieldIndex)
GetFieldValue=Iif(IsNull(pValue),”Null”,pValue)
End If
·在Select Case 语句后缩进
·在Csse语句后缩进
·在Do 语句后缩进
·已经用行接续符分隔的语句的各个行要缩进
·在With 语句后缩进
·在调用Recordset 对象的Edit 和AddNew 方法后缩进。Update 或
ConcelUpdate方法的缩进层次应该与Edit或AddNew 语句相同。
·在调用BeginTrans方法后缩进
·对模块的Declarations 部分中的代码进行缩进,显示其从属关系。
·对所有枚举说明的主体进行缩进。
第二章命令规则
2.1 控件命名
【规则1】控件命名规则见下表
控件类型 前缀 例子
3D Panel pnl pnlGroup
ADO Data ado adoBiblio
Animated button ani aniMailBox
Check box chk chkReadOnly
Combo box cbo cboEnglish
Command button cmd cmdExit
Common dialog dlg dlgFileOpen
Communications com comFax
Control ctr ctrCurrent
Date picker dtp dtpPublished
Data dat datBiblio
Data-bound combo box dbcbo dbcboLanguage
Data-bound grid dbgrd dbgrdQueryResult
Data-bound list box dblst dblstJobType
Data combo dbc dbcAuthor
DataGrid dgd dgdTitles
Data list dbl dblPublisher
Data repeater drp drpLocation
Directory list box dir dirSource
Drive list box drv drvTarget
File list box fil filSource
Flat scroll bar fsb fsbMove
Form frm frmEntry
Frame fra fraLanguage
Gauge gau gauStatus
Graph gra graRevenue
Grid grd grdPrices
Hierarchical flexgrid flex flexOrders
Horizontal scroll bar hsb hsbVolume
Image img imgIcon
Image combo imgcbo imgcboProduct
ImageList ils ilsAllIcons
Label lbl lblHelpMessage
Lightweight check box lwchk lwchkArchive
Lightweight combo box lwcbo lwcboGerman
Lightweight command
button
lwcmd lwcmdRemove
Lightweight frame lwfra lwfraSaveOptions
Lightweight horizontal
scroll bar
lwhsb lwhsbVolume
Lightweight list box lwlst lwlstCostCenters
Lightweight option button lwopt lwoptIncomeLevel
Lightweight text box lwtxt lwtxtStreet
Lightweight vertical
scroll bar
lwvsb lwvsbYear
Line lin linVertical
List box lst lstPolicyCodes
ListView lvw lvwHeadings
MAPI message mpm mpmSentMessage
MAPI session mps mpsSession
MCI mci mciVideo
Menu mnu mnuFileOpen
Month view mvw mvwPeriod
MS Chart ch chSalesbyRegion
MS Flex grid msg msgClients
MS Tab mst mstFirst
OLE container ole oleWorksheet
Option button opt optGender
Picture box pic picVGA
Picture clip clp clpToolbar
ProgressBar prg prgLoadFile
Remote Data rd rdTitles
RichTextBox rtf rtfReport
Shape shp shpCircle
Slider sld sldScale
Spin spn spnPages
StatusBar sta staDateTime
SysInfo sys sysMonitor
TabStrip tab tabOptions
Text box txt txtLastName
Timer tmr tmrAlarm
Toolbar tlb tlbActions
TreeView tre treOrganization
UpDown upd updDirection
Vertical scroll bar vsb vsbRate
2.2 变量命名
【规则2】变量应该总是被定义在尽可能小的范围内。
在Visual Basic中变量可以有下列范围:
范围声明位置 声明 变量范围
过程级过程Private 声明过程中
模块级窗体
代码模块
Private 声明的窗体、模块中
全局 标准模块Public 整个工程
【规则3】尽可能减少使用全局变量。全局(Public) 变量可以导致极其复杂的状态机构,
并且使一个应用程序的逻辑非常难于理解,使代码的重用和维护更加困难。在应用程序中,
只有当没有其它方便途径在窗体之间共享数据时才使用全局变量。
【规则4】当必须使用全局变量时,在一个单一模块中声明它们,并按功能分组。给这个模
块取一个有意义的名称,以指明它的作用。
【规则5】全局变量命令规则:g+名称
模块级变量命令规则:p+名称
范围 前缀 例子
全局 g gstrUserName
模块级p pblnCalcInProgress
本地到过程无 dblVelocity
【规则6】局部变量的命令规则:数据类型缩写+ 名字
数据类型 前缀 例子
Boolean bln blnFound
Byte byt bytRasterData
Collection col colWidgets
Currency cur curRevenue
Double dbl dblTolerance
Error err errOrderNum
Integer int intQuantity
Long lng lngDistance
Object obj objCurrent
Single sng sngAverage
String str strFName
User-def udt udtEmployee
Variant vnt vntCheckSum
【规则8】静态变量加前缀st(表示static)。
例如:
static stinitValue as integer ‘ 静态变量
【规则9】类的数据成员加前缀m(表示member),这样可以避免数据成员与成员函数的
参数同名。
例如:
Public Type student
mnum As String * 8
mname As String * 8
mtotal As String * 8
maverage As Integer
End Type
2.3 常量命名约定
常量与变量不同,它是在设计代码时被赋予值的,这个值不能在运行时更改,使用常
量可以代替硬编码,而且使代码更容易阅读,变得比较直观明了。
常量名建议最好全部大写,使用下划线作为单词间的分隔符,单词尽量使用全名称。
【规则10】常量全用大写的字母,用下划线分割单词
例如:
const MAX = 100
const MAX_LENGTH = 100
【规则11】使用Option Explicit语句要求在Visual Basic 程序中声明所有的变量。
2.4 函数命名约定
此处函数包括Sub和Function,以下将这两个过程统称为函数。
函数表示的是一个动作,所以它的结构应该是动词+名词,动词必须小写,后面的名称首字
母大写,
例如:setWorkspaceEditState
loadDianLanData
setFieldValue
【规则12】函数命令尽量不要使用缩写,而且它的名称应该使人一目了然,必须能够反映
函数的作用,能够从名称就知道这个函数的功能。
【规则13】函数命名必须能准确表达所要实现的功能,不至于引起歧义。
第三章表达式和基本语句
3.1 复合表达式
【规则1】如果代码行中的运算符比较多,用括号确定表达式的操作顺序,避免使用默认的
优先级。
例如: if a>b & a<c
【规则2】不要编写太复杂的复合表达式
例如:i=a>=b &c<d &c+f<=g+h ‘复合表达式过于复杂
【规则3】不可将布尔变量直接与True、False或者1、0进行比较
根据布尔类型的定义,零值为假(记为False),任何非零值都是“真”(记为True)。
True的值究竟是什么并没有统一的标准。
假设布尔变量名字为flag,它与零值比较的标准if 语句如下:
if flag then ‘表示flag 为真
if !flag then ‘表示flag 为假
其他的用法都属于不良风格:
例如:
if flag=True then
if flag=1 then
if flag=false then
【规则4】应当将整型变量用“==”或“!=”直接与0比较。
假设整型变量的名字为Value,它与零值比较的标准if语句如下:
if Value=0 then
if Value <>0 then
3.2 循环语句的效率
For语句使用效率最高,While语句其次,Do语句很少用。本节重点论述循环体的效率。
提高循环体效率的基本办法是降低循环体的复杂性。
【规则5】在程序中尽量避免使用循环,可以用其他方式完成尽量使用其他方式。
【规则6】在多重循环中,如果有可能,应当将最长的循环放在最内层,最短的循环放在最
外层,以减少CPU跨切循环层的次数。
For row=0 to 100
For col=0 to 5
Sum=Sum+a
Next col
Next row
For col=0 to 5
For row=0 to 100
Sum=Sum+a
Next row
Next col
低效率:长循环在最外层高效率:长循环在最内层
【规则7】如果循环体内存在逻辑判断,并且循环次数很大,宜将逻辑判断移到循环体的外
面。
For i=0 to N
If condition then
Dosomething()
Else
Dosomething()
Endif
Next i
If condition then
For i=0 to N
Dosomething()
Next i
Else
For i=0 to N
Dosomething()
Next i
Endif
效率低但程序更简洁效率高但程序不简洁
【规则8】不可在For循环体内修改循环变量,防止For循环失去控制。
【规则9】switch 是多分支选择语句,而If语句只有两个分支可供选择,虽然可以用If语句
的嵌套方式来实现多分支选择,但这样的程序冗长难懂,这时选用Switch较为方便。
3.3 错误处理
运用错误处理程序要达到的目的时:
·防止你的程序崩溃
·可能时恰当地纠正错误
·发生错误时将情况通知用户,以便纠正错误。
【规则10】使用On Error Resume Next以忽略错误
对错误进行处理地最简单同时也是最危险地方法是使用On Error Resume Next语句。
On Error Resume Next语句规定,代码中地错误将完全被忽略,存在错误的代码行被跳
过,然后继续执行下一个语句。
【规则11】使用On Error GoTo转移执行的代码流
转移执行的代码用行标注来指定,行标注是一个文本串,用于标识一个单行代码。行标
注可以是任何字符的组合,它以一个字母开始,以冒号(:)结尾。
第四章优化与性能调节
【规则1】使用正确的数据类型
提高代码运行速度最简单的方法莫过于使用正确的数据类型了。也许你不相信,但是
正确地选择数据类型可以大幅度提升代码的性能。在大多数情况下,程序员可以将Single,
Double和Currency类型的变量替换为Integer或Long类型的变量,因为VB处理Integer
和Long的能力远远高于处理其它几种数据类型。
在大多数情况下,程序员选择使用Single或Double的原因是因为它们能够保存小
数。但是小数也可以保存在Integer类型的变量中。例如程序中约定有三位小数,那么只需
要将保存在Integer变量中的数值除以1000就可以得到结果。根据我的经验,使用Integer
和Long替代Single,Double和Currency后,代码的运行速度可以提高将近10倍。
【规则2】避免使用变体
对于一个VB程序员来说,这是再明显不过的事情了。变体类型的变量需要16个字节
的空间来保存数据,而一个整数(Integer)只需要2个字节。通常使用变体类型的目的是
为了减少设计的工作量和代码量,也有的程序员图个省事而使用它。但是如果一个软件经过
了严格设计和按照规范编码的话,完全可以避免使用变体类型。
在这里顺带提一句,对于Object对象也存在同样的问题。请看下面的代码:
Dim FSO
Set FSO = New Scripting.FileSystemObject
或
Dim FSO as object
Set FSO = New Scripting.FileSystemObject
上面的代码由于在申明的时候没有指定数据类型,在赋值时将浪费内存和CPU时间。正
确的代码应该象下面这样:
Dim FSO as New FileSystemObject
【规则3】尽量避免使用属性
在平时的代码中,最常见的比较低效的代码就是在可以使用变量的情况下,反复使用
属性(Property),尤其是在循环中。要知道存取变量的速度是存取属性的速度的20倍左右。
下面这段代码是很多程序员在程序中会使用到的:
Dim intCon as Integer
For intCon = 0 to Ubound(SomVar())
Text1.Text = Text1.Text & vbcrlf & SomeVar(intCon)
Next intCon
下面这段代码的执行速度是上面代码的20倍。
Dim intCon as Integer
Dim sOutput as String
For intCon = 0 to Ubound(SomeVar())
sOutput = sOutput & vbCrlf &
SomeVar(intCon)
Next
Text1.Text = sOutput
【规则4】尽量使用数组,避免使用集合
除非你必须使用集合(Collection),否则你应该尽量使用数组。据测试,数组的存
取速度可以达到集合的100倍。这个数字听起来有点骇人听闻,但是如果你考虑到集合是一
个对象,你就会明白为什么差异会这么大。
【规则5】避免使用很短的函数
和使用小的循环体相同,调用只有几行代码的函数也是不经济的--调用函数所花费的
时间或许比执行函数中的代码需要更长的时间。在这种情况下,你可以把函数中的代码拷贝
到原来调用函数的地方。
【规则6】减少对子对象的引用
在VB中,通过使用.来实现对象的引用。
例如:
Form1.Text1.Text
在上面的例子中,程序引用了两个对象:Form1和Text1。利用这种方法引用效率很
低。但遗憾的是,没有办法可以避免它。程序员唯一可以做就是使用With或者将用另一个
对象保存子对象(Text1)。
' 使用With
With frmMain.Text1
.Text = "Learn VB"
.Alignment = 0
.Tag = "Its my life"
.BackColor = vbBlack
.ForeColor = vbWhite
End With
【规则7】检查字符串是否为空
大多数程序员在检查字符串是否为空时会使用下面的方法:
If Text1.Text = "" then
' 执行操作
End if
很不幸,进行字符串比较需要的处理量甚至比读取属性还要大。因此我建议大家使用
下面的方法:
If Len(Text1.Text) = 0 then
' 执行操作
End if
【规则8】使用数组,而不是多个变量
当你有多个保存类似数据的变量时,可以考虑将他们用一个数组代替。在VB中,数组
是最高效的数据结构之一。
【规则9】使用动态数组,而不是静态数组
使用动态数组对代码的执行速度不会产生太大的影响,但是在某些情况下可以节约大
量的资源。
【规则10】销毁对象
无论编写的是什么软件,程序员都需要考虑在用户决定终止软件运行后释放软件占用
的内存空间。但遗憾的是很多程序员对这一点好像并不是很在意。正确的做法是在退出程序
前需要销毁程序中使用的对象。
例如:
Dim FSO as New FileSystemObject
' 执行操作
' 销毁对象
Set FSO = Nothing
对于窗体,可以进行卸载:
Unload frmMain
或
Set frmMain = Nothing
【规则11】变长和定长字符串
从技术上来说,与变长字符串相比,定长字符串需要较少的处理时间和空间。但是
定长字符串的缺点在于在很多情况下,你都需要调用Trim函数以去除字符串末的空字符,
这样反而会降低代码效率。所以除非是字符串的长度不会变化,否则还是使用变长字符串。
【规则12】使用内部对象
在涉及到使用ActiveX控件和DLL的时候,很多程序员喜欢将它们编译好,然后再加入
工程中。我建议你最好不要这样做,因为从VB连接到一个外部对象需要耗费大量的CPU处
理能力。每当你调用方法或存取属性的时候,都会浪费大量的系统资源。如果你有ActiveX
控件或DLL的源代码,将它们作为工程的私有对象。
【规则13】减少模块的数量
有些人喜欢将通用的函数保存在模块中,对于这一点我表示赞同。但是在一个模块中只
写上二三十行代码就有些可笑了。如果你不是非常需要模块,尽量不要使用它。这样做的原
因是因为只有在模块中的函数或变量被调用时,VB才将模块加载到内存中;当VB应用程序
退出时,才会从内存中卸载这些模块。如果代码中只有一个模块,VB就只会进行一次加载
操作,这样代码的效率就得到了提高;反之如果代码中有多个模块,VB会进行多次加载操
作,代码的效率会降低。
【规则14】使用对象数组
当设计用户界面时,对于同样类型的控件,程序员应该尽量使用对象数组。你可以做
一个实验:在窗口上添加100个PictureBox,每个PictureBox都有不同的名称,运行程序。
然后创建一个新的工程,同样在窗口上添加100个PictureBox,不过这一次使用对象数组,
运行程序,你可以注意到两个程序加载时间上的差别。
【规则15】使用Move方法
在改变对象的位置时,有些程序员喜欢使用Width,Height,Top和Left属性。例如:
Image1.Width = 100
Image1.Height = 100
Image1.Top = 0
Image1.Left = 0
实际上这样做效率很低,因为程序修改了四个属性,而且每次修改之后,窗口都会被重
绘。正确的做法是使用Move方法:
Image1.Move 0,0,100,100
【规则16】减少图片的使用
图片将占用大量内存,而且处理图片也需要占用很多CPU资源。在软件中,如果可能的
话,可以考虑用背景色来替代图片--当然这只是从技术人员的角度出发看这个问题。
【规则17】使用类模块,而不是ActiveX控件除非ActiveX控件涉及到用户界面,否则尽量
使用轻量的对象,例如类。这两者之间的效率有很大差异。同样的尽量使用ActiveX dll。
【规则18】ListView控件与DataGrid控件的选取。当涉及显示的数据库记录较少时可以选
择ListView控件显示,而当显示记录条数较多时使用DataGrid控件显示。
第五章用户界面设计规范
5.1 界面设计原则
·用户界面设计必须保持一致,界面设计的一致性要达到的目的是:
·创建程序中统一的界面,并且创建不通应用程序中的统一的界面;
·使得用户能够充分利用他们现有的技巧;
·减少用户在操作中的混乱和困难
·形成醒目的界面,建立用户的信息,使得用户感到满意;
·用简明扼要的专业性语言高司用户他们必须知道的消息。
5.2 界面设计基础
【规则1】在规定情况喜爱使用最佳界面组件
·如果TextBox控件仅用于显示数据,可以换成Label控件
·使用滚动条ScrollBar来指明数量和速度
·只有在绝对必要时才选用Picture控件,建议使用Image控件来显示图片
·当允许用户选定和取消选项项目时,应尽量采用复选框CheckBox
·使用列表框ListBox显示带有5个以上项目的动态列表和静态列表
·若运行一段程序需要长时间的等待,使用进度条ProgressBar可以缓和用户的紧张。
【规则2】精心设置所有窗体的Tab键顺序。
【规则3】创建对话框中的默认命令按钮和Cancel(取消)命令按钮。
【规则4】设置与数据域相关联的控件的MaxLength属性。数据库表格中的大多数字段都
有一个它们能够存放的最大字符数。如果试图将超出允许范围的字符数目村翻盖数据表中将
会引起错误。
【规则5】创建功能良好的消息框
信息类消息框(vbInformation)提示比较简单的非危急状况的通知信息。
警告类消息框(vbExclamation)用于将一些非常重要的消息通知用户。
问号图标(vbQuestion)应该用于向用户提出问题的消息框。给用户一个自己选择
的机会。
危急状况消息框(vbCritical)用于将某些绝对必须注意的情况通知用户。
第六章小组开发规范
【规则1】每次对程序编译后应将版本号递增1
编译一个程序或ActiveX组件时,编译文件中就包含一个版本号。这个版本号供安装
程序用于确保文件不会被较老的文件版本改写。若要查看文件的版本号,可以使用Windows
Explorer,查看文件的属性,它能够比较容易地查找安装错误。
版本号的格式通常如下所示:
主.次.修改号
当显示版本信息时,请记住次版本号通常显示为右对齐的4个数字。例如,若要显示
3.1版的第27次修改程序,该版本号应该时下面的形式:
3.1.0027
【规则2】使用Vss来维护源代码的版本
对于复杂的项目,应该考虑使用Visual SouceSafe来管理项目。Visual SouceSafe
能够跟踪项目中所有文件的所有修改版本,使你能在必要时很容易转到某个版本。