三、模块和过程设计的原则
1、为过程和模块赋予表义性强的名字
为了使代码更加容易理解,最容易的方法之一是为我们的过程赋予表义性强的名字。函数名DoIt、GetIt和PrintIt的可读性很难与CalculateSalesTax、RetrieveUserID和PrintSpreadSheet相比。给过程正确地命名,可使程序工程的调试和维护工作大大改观。我们要认真对待过程命名的工作,不要为了减少键入操作量而降低过程的可理解度。给过程命名时应该大小写字母混合使用,定义过程名时不要使用缩写。这些都是初学者必须要牢记的。下面是一些例子:
不正确:
Private Function InvoicePost()As Boolean Private Function PrintIt()As Boolean Public Sub SaveItem() Public Sub DeleteRecord() |
正确:
Private Function PostInvoice()As Boolean Private Function PrintSpreadsheet()As Boolean Public Sub SavePicture() Public Sub DeleteContact() |
2、为每个过程赋予明确定义的作用域
作用域是指工程中的变量或过程的可视性。过程可以定义为拥有模块级作用域、全局作用域或友元作用域。当一个过程用Private关键字来说明时,便拥有模块级作用域,并且它只能用同一模块中的过程来调用。如果用关键字Public来说明一个过程,那么这个过程将拥有全局作用域,并且可以用工程中的任何模块来调用。此外,公用类模块的公用过程可用于外部程序。用Friend关键字说明的(公用类模块中的)过程将使该过程成为工程中的所有模块的公用过程,但是它不能使该过程成为外部程序的公用过程。创建过程时,始终都应显式地定义它的作用域。虽然不使用Public Private或Friend将无法定义一个过程,但是我们应该避免这样进行操作。
在许多情况下,我们不用Public、Private或Friend说明的过程实际上将作为模块级(专用)过程来使用。但是,如果不专门说明为专用过程,它们就会无意中创建为公用过程。通过为每个过程赋予一个明确定义的作用域,可以减少代码阅读者需要投入的工作量。另外,应该确保我们为过程赋予最有意义的作用域。如果一个过程只被同一模块中的另一个过程调用,那么请将它创建成专用过程。如果该过程是从多个模块中的多个过程中调用,请将该过程说明为公用过程。每个过程的定义都应该以Public、Private或Friend开头。如果现有的过程不带有这些关键字中的一个,那么我们就必须遍历工程,以便确定每个过程的作用域,并相应地修改其说明。
不正确:
Sub CalculatePOTotals( ) … End Sub |
正确:
Public Sub CalculatePOTotals( ) … End Sub |
3、用参数在过程之间传递数据
虽然模块级变量的问题不像全局变量那么多,但是我们也应该尽量避免使用模块级变量。一般来说,变量的作用域越小越好。为了减少模块级变量和全局变量,方法之一是将数据作为参数在不同过程之间传递,而不是让过程共享全局变量或模块级变量。
例如为每个参数指定数据类型。这个问题应该给予充分的重视。创建带有参数的过程时,请务必将每个参数明确说明为一个特定的数据类型。当我们省略参数说明中的As<type>部分时,该参数将作为Variant(变码)来创建。如果我们想创建Variant参数,请使用As Variant进行显式创建。
不正确:
Private Sub CreateStockRecord(ItemID, Repair, Quantity) |
正确:
Private Sub CreateStockRecord(strItemID As String, blnRepair _ As Boolean, sngQuantity As Single) |
4、使用统一和直观明了的方式来调用过程
VB提供了许多快捷操作方式,可供在编写代码时使用。一般来说,这些快捷方式不影响代码的运行性能,但是它们往往牺牲了代码的可读性,以便在进行软件开发时省去一些击键操作。应该尽量使代码做到直观明了。有的时候,也就是当调用过程的时候,可以采用快捷方式,然而我们不应该这样去做。
我们可以用许多不同的方法来调用一个过程。当调用Sub过程时,可以使用单词Call,也可以省去这个单词。例如,下面这两个语句均调用相同的Sub过程:
CallShowError("clsApplication","ShowRep",Err.Number,Err.Description) ShowError"clsApplication","ShowRep",Err.Number,Err.Description |
虽然可以省略单词Call,这样我们就不必键入两个括号来启动代码,但是我们应该避免使用这种方法。关键字Call专门用来指明该语句是调用一个Sub过程,而不是调用Function过程,因此它使代码更容易阅读。
VB允许我们以完全相同的方法来调用Sub过程和Function过程。请看下面这个函数:
Public Function DisplayContact(lngContactNumber As Long) As Boolean … End Function |
我们可以使用下面的任何一个语句来调用该函数:
Call ShowRep(lngRepNumber) ShowRep lngRepNumber blnResult=ShowRep(lngRepNumber) |
为了使代码尽可能直观明了,必须将调用Sub过程与调用Function过程区分开来。调用Sub过程时,始终都应使用关键字Call;调用Function过程时,始终都应检索Function调用的值,即使我们并不使用这个值,也应这么做。
查看本文来源