面向对象的编程范式具有很多明显的优点。比如更高的代码重用、封装带来的更好的模块边界、更直观和简单地调用程序以及面向对象的思考方法能有效地解决问题。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的语法对象,给出一个易于使用的接口。除了上面提到的操作,这个接口还提供了如下一些方法:
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编辑器充分发挥。