http://lingobuddy.51.net/larry/index.php/2004/12/effective-visual-basic/
Effective Visual Basic: How to Improve Your VB/COM+ Applications
by Joe Hummel, Ted Pattison, Justin Gehtland, Doug Turnure, Brian A. Randell, Copyright© 2001
ISBN: 0-201-70476-5
http://www.developmentor.com
Visual Basic高效编程:改进VB/COM+应用程序
简体中文版 Copyright© 2003 by Pearson Education Asia Ltd. & Tsinghua University Press.
严静东 郭文明 等译 战晓苏 主审
清华大学出版社 2003.12
http://www.tup.com.cn
ISBN: 7-302-07701-0
TP·5639
第1章 由随意编程转变为遵循软件工程原则
# 命名规则:
## 类型前缀:
C 自定义类
I 自定义接口
T UDT
## 变量前缀:
a 数组
b 布尔
c 货币
col Collection
db ADO Connection
e Enum变量
i 整数
l 长整数
r 对象引用
rs ADO Recordset
s String
txt TextBox控件
u UDT变量
v Variant变量
# 补充:
模块内部变量 m_
模块内部常量 mc_
工程全局变量 g_
工程全局常量 gc_
Private 方法/属性前缀 p
Friend 方法/属性前缀 f
工程组名称前缀 g
1.1 规则1-1:最大限度地发挥VB编译期类型检查的潜能
# 最好能让错误在编译期就暴露出来。
# VB类型检查较弱
1.1.1 在每个模块的顶端使用 Option Explicit 语句
# 不用该选项可能使错误被隐蔽
1.1.2 避免不经意地使用 Variant 数据类型
# 不指定类型的变量默认为 Variant
# 适合使用Variant的场合:从数据库读取的字段值;脚本使用的类(VBScript只支持ByRef方式的调用)
1.1.3 在VB IDE中运行时, 使用Start With Full Compile命令
# Tools | Options, General: Compile on Demand
1.2 规则1-2:使用Debug.Assert显式声明假设
# 假设包括外部假设(如文件存在) 和内部假设如:Dim i As Integer
For i = 0 To UBound(A)
…
# 注意在多人协作时可能出现不同的假设,带来逻辑错误。
# 对外部传入的对象通过Debug.Assert说明本函数中的假设,如 Not rs.EOF,或 TypeOf ctrl Is ListBox。
# Debug.Assert有助于测试、集成和维护时发现逻辑错误,应当在代码中保留并维护起来。
#集成环境外可以定义自己的Assert子程序:Public Sub Assert(bCondition As Boolean, sMsg As String)
#If ASSERT_OUTSIDE_IDE Then
If Not bCondition Then
App.LogEvent “Assertion failed: ” & sMsg
End If
#End If
#If ASSERT_INSIDE_IDE Then
If Not bCondition Then
Debug.Print “Assertion failed: ” & sMsg
Debug.Assert False
End If
#End If
End Sub
1.3 规则1-3:编译期条件不同时, 考虑使用#If语句
#If Debug_X <> 0 Or Debug_All <> 0 Then
# 优先顺序:
Project Properties对话框 < - 模块内#Const <- vb6.exe /make prj.vbp /d VAR=1 命令行参数
# 适度:如果只有细微差别,用条件编译生成多个版本可能代价太大
1.4 规则1-4:抛出错误以提示异常
# 抛出错误之前,注意应该尽可能显式地清除子例程的状态,如关闭ADO Connection, Recordset等
1.5 规则1-5:有效的错误处理:局部捕获, 全局处理
# 调用可能产生错误的API函数之后,需要检查API错误码
# 全局处理错误的方案 ErrHdl.rar
1.6 规则1-6:了解类型和类的区别
# 类具有多态性的优点
# 注意:只有Public类模块中定义的UDT可以存储在Variant变量中
1.7 规则1-7:采用面向对象的设计方法
1. 封装:把数据和代码打包到一个类当中,把真实世界中的实体的状态和行为映射到类的属性和方法。
2. 抽象:抽取重复使用的代码,增加对象的方法,简化客户程序使用对象完成任务的步骤
3. 数据隐藏:隐藏服务类的实现细节,屏蔽服务类实现细节变化对客户程序的影响。
# 自定义可以 For Each 迭代的类
Procedure Attributes: ID = -4
Public Function NewEnum() As IUnknown
Set NewEnum = colItems.[_NewEnum]
End Function
# 控制抽象程度,避免过度设计。原则是从类的客户角度考虑设计是否方便使用。
1.8 规则1-8:推荐采用用户自定义类型而不是类来定义值类型
# 创建类对象开销较大。
# 跨进程调用时UDT可以传递数值副本,而访问类的成员将需要跨进程调度。
# 所以,当执行效率问题很重要时,尽可能用UDT代替不必要的类。
1.9 规则1-9:一般任务的自动化
# 使用nmake编译。可以根据依赖关系选择编译必要的部分。
TARGETS = C1.dll C2.dll
VB = “PathToVB6.EXE”
ARGS = /d DBUG = 1
component: $(TARGETS)
C1.dll: C1.vbp Class1.cls Class2.csl
$(VB) /make C1.vbp $(ARGS)
…
C2.dll: …
.SUFFIXES: .vbp .frm .cls .bas
clean:
regsvr32 /u /s $(TARGETS)
del $(TARGETS)
# 使用WSH对象模型
Set rScriptArgs = WScript.Arguments
If rScriptArgs.Count <> 1 Then
WScript.Echo “Usage: …”
WScript.Quit(1)
End If
Set rFS = WScript.CreateObject("Scripting.FileSystemObject")
Set sShell = WScript.CreateObject("WScript.Shell")
rShell.Popup
rShell.Run sVB & sC1 & sARGS, 0, True
# 可以结合makefile和WSH自动化日常任务。
# 用VB6 IDE创建工程,引用Windows Script Host Object Model可以利用自动完成功能帮助书写VBS脚本。