Skip to content

迭代器模式

提供一种方法顺序访问集合对象中的元素,而又不暴露其内部结构

适合的场景

  • 你想遍历集合里的元素,但不想暴露集合的底层结构

  • 你有多个集合类(List、Set、Tree…)想统一遍历方式

  • 你想自定义复杂的遍历逻辑(比如倒序、跳步、筛选遍历等)

举个例子:

你有一个宝箱,里面有魔法石、金币、药水……

你想挨个取出来看看,但不想知道宝箱怎么锁的、怎么分类的

——那就给你一个“迭代器”,让你专心翻东西就好!

基本结构

plain text
Client(使用者)

Iterator(迭代器接口)
   └── ConcreteIterator(具体迭代器)

Aggregate(集合接口)
   └── ConcreteAggregate(具体集合)
  • Client(使用者)

  • Iterator(迭代器接口)

  • ConcreteIterator(具体迭代器)

  • Aggregate(集合接口)

  • ConcreteAggregate(具体集合)

示例

我们来写个简单的“宝箱”集合,它装着道具,然后用迭代器一件件拿出来

csharp
// 迭代器接口
interface IItemIterator 
{
    bool HasNext();
    string Next();
}

// 集合接口
interface IItemCollection 
{
    IItemIterator CreateIterator();
}

// 具体集合
class TreasureBox : IItemCollection 
{
    private List<string> _items = new() { "Potion", "Gold", "Magic Stone" };

    public IItemIterator CreateIterator() => new TreasureIterator(this);

    public string Get(int index) => _items[index];
    public int Count => _items.Count;

    // 具体迭代器
    private class TreasureIterator : IItemIterator 
    {
        private TreasureBox _box;
        private int _index = 0;
        public TreasureIterator(TreasureBox box) => _box = box;

        public bool HasNext() => _index < _box.Count;
        public string Next() => _box.Get(_index++);
    }
}

// 使用
var box = new TreasureBox();
var iterator = box.CreateIterator();
while (iterator.HasNext())
    Console.WriteLine(iterator.Next());

GDScript示例

gdscript
# 宝箱
class TreasureBox:
    var items = ["Potion", "Gold", "Magic Stone"]

    func create_iterator():
        return TreasureIterator.new(self)

    # 迭代器
    class TreasureIterator:
        var box
        var index = 0
        func _init(b): box = b
        func has_next() -> bool:
            return index < box.items.size()
        func next():
            var item = box.items[index]
            index += 1
            return item

# 使用
func _ready():
    var box = TreasureBox.new()
    var it = box.create_iterator()
    while it.has_next():
        print(it.next())