面向对象的编程范式具有很多明显的优点。比如更高的代码重用、封装带来的更好的模块边界、更直观和简单地调用程序以及面向对象的思考方法能有效地解决问题。LotusScript作为一种基于对象的脚本语言,虽然不具备完全面向对象的语言的一些特性,但是仍然可以使用它编写出面向对象的程序。DominoDesigner中的LotusScript编辑器曾经一直为人诟病的一点就是对自定义的类的支持不友好,最突出的就是没有提供类视图和在输入帮助中加入自定义类。部分地因为这个,Notes程序员更多的还是使用面向过程的范式。R8.5给Notes开发带来了巨大的变化。XPage这一项以JSF为基础的开发技术使得Notes程序有希望摆脱被边缘化的危险。这一仍然处于新生期的技术还具有不少缺点,缺乏翔实准确的资料,实例不多,bug不少。而本文要谈的是以Eclipse为基础的新的Designer给传统的LotusScript开发带来的明显好处--新的脚本编辑器具备上面提到的给程序员帮助最大的两项特性。这样祛除了工具上的不便,就可以充分发挥面向对象的编程范式的优点。
下面我就用一个实例来说明面向对象的范式。
LotusScript提供了List这样一种数据结构,它实现的功能就是被其他的面向对象的语言称为Dictionary,Map之类的东西。LotusScript通过 ListName(tag),ListTag(), IsElement(), Erase这样一些语法规则、语句和函数来实现读、写、检查和清除等操作。而面向对象的语言则通过相应的类的方法来提供这些功能。相比之下,我更喜欢后者的处理方式,因此编写了一个LotusScript的自定义类Dictionary。它简单地封装了LotusScript处理List的语法对象,给出一个易于使用的接口。除了上面提到的操作,这个接口还提供了如下一些方法:
下面我就用一个实例来说明面向对象的范式。
LotusScript提供了List这样一种数据结构,它实现的功能就是被其他的面向对象的语言称为Dictionary,Map之类的东西。LotusScript通过 ListName(tag),ListTag(), IsElement(), Erase这样一些语法规则、语句和函数来实现读、写、检查和清除等操作。而面向对象的语言则通过相应的类的方法来提供这些功能。相比之下,我更喜欢后者的处理方式,因此编写了一个LotusScript的自定义类Dictionary。它简单地封装了LotusScript处理List的语法对象,给出一个易于使用的接口。除了上面提到的操作,这个接口还提供了如下一些方法:
GetList 返回内部使用的list
GetKeys 返回list的键为一个变量数组
GetValues 返回list的值为一个变量数组
%REM
Class Dictionary
Description: Comments for Class
%END REM
Public Class Dictionary
Private dic List As Variant
Private count As Long
%REM
Sub New
Description: Comments for Sub
%END REM
Sub New()
End Sub
Sub Delete()
Erase dic
End Sub
%REM
Function GetList
Description: Comments for Function
%END REM
Public Function GetList()
GetList=dic
End Function
%REM
Function GetKeys
Description: Get the keys in the list as a variant array
%END REM
Public Function GetKeys()
Dim keys As New NArray(-1)
ForAll v In dic
keys.Add(ListTag(v))
End ForAll
GetKeys=keys.container
End Function
%REM
Function GetValues
Description: Get the values in the list as a variant array
%END REM
Public Function GetValues()
Dim values As New NArray(-1)
ForAll v In dic
values.Add(v)
End ForAll
GetValues=values.container
End Function
%REM
Function Add
Description: Comments for Function
%END REM
Public Function Add(key As String, value As Variant)
If IsObject(value) Then
Set dic(key)=value
Else
dic(key)=value
End If
End Function
%REM
Function Item
Description: Comments for Function
%END REM
Public Function Item(key As String) As Variant
'Handle the ErrListItemDoesNotExist error explicitly
If Not me.Contains(key) Then
Exit Function
End If
If IsObject(dic(key)) Then
Set Item=dic(key)
Else
Item=dic(key)
End If
End Function
%REM
Function RemoveItem
Description: Remove the element associated with the key
'Remove' cannot be used as the function name
%END REM
Public Function RemoveItem(key As String)
Erase dic(key)
End Function
%REM
Function Clear
Description: Comments for Function
%END REM
Public Function Clear()
Erase dic
End Function
%REM
Function Contains
Description: Comments for Function
%END REM
Public Function Contains(key As String) As Boolean
If IsElement(dic(key)) Then
Contains=True
Else
Contains=False
End If
End Function
End Class
在一个代理中测试这个自定义类。
Public Function Test()
Dim d As New Dictionary
Call d.Add("first", 1)
logger.info(d.Contains("first"))
logger.info(d.Contains("second"))
logger.info(d.Item("first"))
Call d.RemoveItem("first")
logger.info(d.Contains("first"))
End Function
其中,logger是该代理中使用的另一个用于记录日志的类的实例。测试结果如下:
11/2/2011 10:20:58 AM[INFO] - True
11/2/2011 10:20:58 AM [INFO] - False
11/2/2011 10:20:58 AM [INFO] - 1
11/2/2011 10:20:58 AM [INFO] - False
与使用LotusScript自带的处理List的语法规则相比,上述的自定义类在使用时更加方便和符合面向对象的程序的惯例,这还仅仅是小小的便利和习惯上的偏好,并没有完全体现面向对象的编程范式的优点,而这些优点,都可以利用新的LotusScript编辑器充分发挥。