“数据结构” 模式
- 常常有一些组件在内部具有特定的数据结构,如果让客户程序依赖这些特定的数据结构,将极大地破坏组件的复用。这时候,将这些特定的数据结构封装在内部,在外部提供统一的接口,来实现与特定数据结构无关的访问,是一种行之有效的解决方案。
- 典型模式
- Composite
- Iterator
- Chain of Resposibility
一、场景分析
一个集合对象,如列表(list),应该提供一种方法来让别人可以访问它的元素,而又不需暴露它的内部结构。此外,针对不同的需要,可能要以不同的方式遍历这个列表。但是即使可以预见到所需的那些遍历操作,你可能也不希望列表的接口中充斥着各种不同遍历的操作。有时还可能需要在同一个列表上同时进行多个遍历。
迭代器模式都可帮你解决所有这些问题。这一模式的关键思想是将对列表的访问和遍历从列表对象中分离出来并放入一个迭代器(iterator)对象中。迭代器类定义了一个访问该列表元素的接口。迭代器对象负责跟踪当前的元素;即,它知道哪些元素已经遍历过了。
例如,一个列表类(List)可能需要一个列表迭代器(ListIterator),它们之间的关系如下图:
在实例化列表迭代器之前,必须提供待遍历的列表。一旦又了该列表迭代器的实例,就可以顺序地访问该列表的各个元素。CurrentItem操作返回列表中的当前元素,First操作初始化迭代器,使当前元素指向列表的第一个元素,Next操作将当前元素指针向前推进一步,指向下一个元素,而IsDone检查是否已越过最后一个元素,也就是完成了这次遍历。
将遍历机制与列表对象分离使我们可以定义不同的迭代器来实现不同的遍历策略,而无序在列表接口中列举它们。例如,过滤表列迭代器(FilteringListIterator)可能只访问那些满足特定过滤约束条件的元素。
这里的迭代器和列表是耦合在一起的,而且客户对象必须知道遍历的是一个列表,而不是其他聚合结构。为了解决这个问题,我们可以把列表和迭代器都提取出抽象
二、动机
提供一种方法顺序访问一个集合对象中的各个元素,而又不需暴露该对象的内部表示。
三、定义
类图:
类图中的各个角色:
- Iterator(迭代器)
- 迭代器定义访问和遍历元素的接口
- ConcreteIterator(具体迭代器)
- 具体迭代器实现迭代器接口
- 对该集合遍历时跟踪当前位置
- Aggregate(聚合)
- 集合接口
- ConcreteAggregate
- 具体集合实现创建相应迭代器的接口,该操作返回ConcreteIterator的一个适当的实例