首页 > 其他 > 详细

98. 面向对象的LotusScript(十七)之LinkedCollection

时间:2015-03-24 16:18:58      阅读:242      评论:0      收藏:0      [点我收藏+]

面向对象编程经常会用到作为容器的对象,使用LotusScript时因为基本上是和单一的数据对象NotesDocument打交道,用作容器的就是数据库的视图或包含搜索结果的文档集合。但有时也需要某个通用容器来容纳其他自定义的对象。此时一般可考虑用数组,或者像20. 面向对象的LotusScript(三)之NArray介绍的编写一个基于动态数组的容器类。本文给出另一种容器的实现方式,对外的接口也像NArray一样是一个Collection,内部实现则不依赖于数组,而采用链接的节点。由于LotusScript的数组在包含数组时有层次上的限制,所以本容器类在理论上适用范围更广(虽然极少遇到这样极端的情况,基本上还是作为一个普通的容器类使用)。

‘先定义一个用作节点的类
Class LinkedNode
    Public PreviousNode As LinkedNode
    Public NextNode As LinkedNode
    Public Value As Variant

    ‘prevNode As LinkedNode, nextNode As LinkedNode
    Sub New(value As Variant)
        Call SetValue(me.Value, value)
    End Sub 

    Sub Append(nnode As LinkedNode)
        Set me.NextNode=nnode
        Set nnode.PreviousNode=Me
    End Sub 

    Function IsEqualTo(node As LinkedNode) As Boolean
        If node Is Me Then
            IsEqualTo=True
            Exit Function 
        End If

        If Equals(node.Value, me.Value) Then
            IsEqualTo=True
        Else
            IsEqualTo=False             
        End If
    End Function
End Class
‘接下来是链接集合类
Class LinkedCollection
    Private msize As Integer
    Private anchor As LinkedNode
    Private current As LinkedNode
    ‘Public Parent As LinkedCollection

    Sub New()
        Set anchor=New LinkedNode(Null)
        Call anchor.Append(anchor)
        Call Me.Reset()
        ‘Set anchor.PreviousNode=anchor
        ‘Set anchor.NextNode=anchor
    End Sub

    Property Get Size As Integer
        Size=msize
    End Property

    Function FirstNode() As LinkedNode
        Dim node As LinkedNode
        Set node=anchor.NextNode
        If Not anchor.NextNode Is anchor Then
            Set FirstNode=anchor.NextNode
        End If
    End Function

    Function LastNode() As LinkedNode
        If Not anchor.PreviousNode Is anchor Then
            Set LastNode = anchor.PreviousNode
        End If 
    End Function

    Sub Reset()
        Set current=anchor
    End Sub

    Function HasNext() As Boolean
        HasNext=Not current.NextNode Is anchor
    End Function

    Function Next() As LinkedNode
        Set current=current.NextNode
        If current Is anchor Then
            Set Me.Next=Nothing 
            ‘Error 4000, "LinkedList: no such element."
        End If
        Set Me.Next=current
    End Function 

    Function Add(value As Variant)
        Dim node As New LinkedNode(value)
        Call anchor.PreviousNode.Append(node)
        Call node.Append(anchor)
        msize=msize+1
    End Function

    Function Contains(value As Variant) As Boolean
        If Find(value) Is Nothing Then
            Contains=False
        Else
            Contains=True 
        End If
    End Function

    Function ContainsNode(node As LinkedNode) As Boolean
        Call Me.Reset()
        While HasNext()
            If Me.Next() Is node Then
                ContainsNode=True   
            End If
        Wend        
        ContainsNode=False 
    End Function

    Function Remove(value As Variant) As Boolean
        Dim node As LinkedNode
        Set node=Find(value)
        If node Is Nothing Then
            Me.Remove=False 
        Else
            Call DirectRemoveNode(node)
            Me.Remove=True 
        End If      
    End Function

    Function RemoveCurrent() As Boolean
        If current Is anchor Then
            RemoveCurrent=False
        Else
            Call DirectRemoveNode(current)
            Set current=current.PreviousNode
        End If
    End Function

    Private Sub DirectRemoveNode(node As LinkedNode)
        Call node.PreviousNode.Append(node.NextNode)
        msize=msize-1       
    End Sub

    Function Find(value As Variant) As LinkedNode
        Dim node As LinkedNode 
        Call Me.Reset()
        While HasNext()
            Set node=Me.Next()
            If Equals(value, node.Value) Then
                Set Find=node
                Exit Function 
            End If
        Wend        
    End Function

    Function Clone() As LinkedCollection
        Dim col As New LinkedCollection
        ‘Dim node As LinkedNode
        Call Me.Reset()
        While HasNext()
            Call col.Add(Me.Next().Value)   
        Wend
        ‘Set col.Parent=me.Parent
        Set Clone=col
    End Function

    Function AddArray(array As Variant)
        ForAll e In array
            Add(e)
        End ForAll
    End Function

    ‘The node value of two LinkedCollection instances must not point to their 
    ‘ancestors of LinkedCollection in the same hierarchy level. Or an infinite loop
    ‘will occur during comparing these two instances.   
    Function IsEqualTo(lc As Variant) As Boolean
        If Not InstanceOf(lc, TypeName(Me)) Then
            IsEqualTo=False
            Exit Function           
        End If

        If lc Is Me Then
            IsEqualTo=True
            Exit Function           
        End If

        If lc.Size >< me.Size Then
            IsEqualTo=False
            Exit Function           
        End If

        Dim c1 As LinkedCollection, c2 As LinkedCollection      
        Set c1=Me.Clone()
        Set c2=lc.Clone()
        Call c1.Reset()
        Call c2.Reset()
        While c1.HasNext()
            If c2.Remove(c1.Next().Value) Then
                Call c1.RemoveCurrent()             
            Else
                IsEqualTo=False
                Exit Function 
            End If
        Wend
        IsEqualTo=True 
    End Function
End Class

该集合类的方法从名称上都可以看出含义,包括添加单个值、添加数组、克隆、判断是否包含某值、查找包含某值的节点、返回首个节点、判断是否还有下个节点、用于比较等值的IsEqualTo、返回末个节点、返回下个节点、删除包含某值的节点、删除当前节点、重置内部指针以及返回集合包含节点的数量。
其中Reset、HasNext和Next三个方法合起来用于遍历集合内所有的节点:

Call col.Reset()
If col.HasNext() Then
    Set node=col.Next()
    value=node.Value ‘或Set value=node.Value
End If

注意LinkedCollection和LinkedNode类都有一个IsEqualTo方法,可以被87. 再谈变体型Variant里介绍的计算相等性的Equals函数调用。
另外在LinkedCollection的链接实现方式上,采用了一个特殊的初始节点作为“锚”,使得对于从零到任意多个节点,在返回首位节点、添加节点、判断是否有下个节点等操作时,都有一致简单的逻辑。

98. 面向对象的LotusScript(十七)之LinkedCollection

原文:http://blog.csdn.net/starrow/article/details/44591785

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!