【行为型之迭代器模式】游戏开发实战——Unity高效集合遍历与场景管理的架构精髓

文章目录

🔄 迭代器模式(Iterator Pattern)深度解析

------以Unity实现高效集合遍历动态场景管理为核心案例


一、模式本质与核心价值

核心目标

统一集合遍历接口 ,无需暴露内部数据结构

支持多种遍历方式 (顺序、逆序、过滤等)

解耦集合结构与遍历算法,提升代码扩展性

关键术语

  • Iterator(迭代器接口):定义遍历操作(Next、HasNext等)
  • ConcreteIterator(具体迭代器):实现特定遍历逻辑
  • Aggregate(聚合接口):定义创建迭代器的方法
  • ConcreteAggregate(具体聚合):实现集合数据结构

数学表达

设集合C有元素{e₁, e₂, ..., eₙ},迭代器I满足:

I© → e₁ → e₂ → ... → eₙ


二、经典UML结构

creates <<interface>> IIterator +HasNext() : bool +Next() : object InventoryIterator -_items: Item[] -_index: int +HasNext() +Next() <<interface>> IAggregate +CreateIterator() : IIterator Inventory -_items: Item[] +CreateIterator()


三、Unity实战代码(背包系统遍历)
1. 定义迭代器与聚合接口
csharp 复制代码
public interface IIterator<T> {
    bool HasNext();
    T Next();
    void Reset();
}

public interface IAggregate<T> {
    IIterator<T> CreateIterator();
    int Count { get; }
    T this[int index] { get; }
}
2. 实现具体聚合类(背包物品集合)
csharp 复制代码
public class Inventory : IAggregate<Item> {
    private List<Item> _items = new();
    
    public void AddItem(Item item) => _items.Add(item);
    
    public IIterator<Item> CreateIterator() => new InventoryIterator(this);
    
    public int Count => _items.Count;
    
    public Item this[int index] => _items[index];
}
3. 实现具体迭代器
csharp 复制代码
public class InventoryIterator : IIterator<Item> {
    private Inventory _inventory;
    private int _index;
    
    public InventoryIterator(Inventory inventory) {
        _inventory = inventory;
        _index = -1;
    }
    
    public bool HasNext() => _index < _inventory.Count - 1;
    
    public Item Next() => _inventory[++_index];
    
    public void Reset() => _index = -1;
}
4. 客户端使用
csharp 复制代码
public class InventoryUI : MonoBehaviour {
    [SerializeField] private Inventory _inventory;
    
    void Update() {
        if(Input.GetKeyDown(KeyCode.I)) {
            StartCoroutine(DisplayItems());
        }
    }
    
    private IEnumerator DisplayItems() {
        var iterator = _inventory.CreateIterator();
        while(iterator.HasNext()) {
            Item item = iterator.Next();
            Debug.Log($"物品:{item.Name}");
            yield return null; // 分帧显示避免卡顿
        }
    }
}

四、模式进阶技巧
1. 过滤迭代器(按类型遍历)
csharp 复制代码
public class WeaponIterator : IIterator<Item> {
    private IIterator<Item> _baseIterator;
    
    public WeaponIterator(Inventory inventory) {
        _baseIterator = inventory.CreateIterator();
    }
    
    public bool HasNext() {
        while(_baseIterator.HasNext()) {
            if(_baseIterator.Next() is Weapon) {
                _baseIterator.ResetToPrevious();
                return true;
            }
        }
        return false;
    }
    
    public Item Next() => _baseIterator.Next();
}
2. 协程分帧遍历
csharp 复制代码
public static class IteratorExtensions {
    public static IEnumerator CoIterate<T>(this IIterator<T> iterator, Action<T> action) {
        while(iterator.HasNext()) {
            action(iterator.Next());
            yield return null; // 每帧处理一个元素
        }
    }
}

// 使用示例
StartCoroutine(_inventory.CreateIterator().CoIterate(item => {
    // 处理每个物品
}));
3. 双向迭代器
csharp 复制代码
public interface IBidirectionalIterator<T> : IIterator<T> {
    bool HasPrevious();
    T Previous();
}

public class InventoryBidirectionalIterator : IBidirectionalIterator<Item> {
    // 实现前后遍历逻辑
}

五、游戏开发典型应用场景
  1. 场景对象管理

    csharp 复制代码
    public class SceneObjectManager : IAggregate<GameObject> {
        private List<GameObject> _objects = new();
        
        public IIterator<GameObject> CreateIterator() => new SceneObjectIterator(this);
    }
  2. 技能效果链

    csharp 复制代码
    public class SkillEffectChain : IAggregate<IEffect> {
        public IIterator<IEffect> CreateReverseIterator() {
            return new ReverseEffectIterator(this);
        }
    }
  3. AI决策评估

    csharp 复制代码
    public class AIEvaluator {
        public void EvaluateAll(IIterator<AICondition> conditions) {
            while(conditions.HasNext()) {
                var condition = conditions.Next();
                condition.Evaluate();
            }
        }
    }
  4. 动态生成系统

    csharp 复制代码
    public class WorldGenerator {
        public void GenerateChunks(IIterator<Vector3> positionIterator) {
            while(positionIterator.HasNext()) {
                GenerateChunkAt(positionIterator.Next());
            }
        }
    }

六、性能优化策略
策略 实现方式 适用场景
批处理迭代 每次处理多个元素 大规模数据集
缓存迭代器 复用迭代器实例 频繁遍历操作
惰性求值 需要时再计算元素 复杂对象集合
空间分区 结合四叉树/八叉树 3D场景遍历

七、模式对比与选择
维度 迭代器模式 访问者模式
关注点 遍历机制 数据操作
扩展性 新增迭代方式 新增操作类型
数据结构耦合 低耦合 需要接受访问者接口
典型场景 集合遍历 复杂数据结构操作

八、最佳实践原则
  1. 单一职责原则:迭代器只关注遍历逻辑

  2. 不可变快照 :在迭代过程中防止集合修改

    csharp 复制代码
    public class SnapshotIterator<T> : IIterator<T> {
        private readonly T[] _snapshot;
        // 基于快照的迭代实现...
    }
  3. 异常处理 :处理边界条件

    csharp 复制代码
    public T Next() {
        if(!HasNext()) throw new InvalidOperationException("No more elements");
        // ...
    }
  4. 资源释放 :实现IDisposable接口

    csharp 复制代码
    public class FileLineIterator : IIterator<string>, IDisposable {
        private StreamReader _reader;
        public void Dispose() => _reader?.Dispose();
    }

九、常见问题解决方案

Q1:如何避免遍历时集合被修改?

→ 使用读写锁副本迭代

csharp 复制代码
public class ThreadSafeIterator<T> : IIterator<T> {
    private ReaderWriterLockSlim _lock;
    // 在Next/HasNext中加读锁...
}

Q2:如何实现复杂条件过滤?

→ 使用组合过滤器

csharp 复制代码
public class CompositeFilterIterator<T> : IIterator<T> {
    private List<Predicate<T>> _filters = new();
    
    public void AddFilter(Predicate<T> filter) {
        _filters.Add(filter);
    }
    
    public bool HasNext() {
        while(_baseIterator.HasNext()) {
            var item = _baseIterator.Peek();
            if(_filters.All(f => f(item))) return true;
            _baseIterator.Next();
        }
        return false;
    }
}

Q3:如何优化大型场景遍历性能?

→ 实现空间分区迭代器

csharp 复制代码
public class QuadTreeIterator : IIterator<GameObject> {
    private QuadTree _quadTree;
    private List<QuadTreeNode> _nodeStack = new();
    
    public bool HasNext() {
        while(_nodeStack.Count > 0) {
            var current = _nodeStack.Last();
            if(current.HasChildren) {
                // 处理子节点...
            } else {
                return current.Objects.Count > 0;
            }
        }
        return false;
    }
}

上一篇 【行为型之解释器模式】游戏开发实战------Unity动态公式解析与脚本系统的架构奥秘
下一篇 【行为型之中介者模式】游戏开发实战------Unity复杂系统协调与通信架构的核心秘诀

相关推荐
..活宝..5 分钟前
【Emgu CV教程】11.2、Scharr边缘检测
图像处理·计算机视觉·c#·emgu cv·图像分析
yngsqq5 分钟前
事件监听 ——CAD C#二次开发
c#
The Kite39 分钟前
MPLAB X IDE 软件安装与卸载
ide·c#·嵌入式
hstar95271 小时前
三十三、面向对象底层逻辑-SpringMVC九大组件之HandlerExceptionResolver接口设计
java·spring·设计模式·架构
张鱼小丸子_微辣4 小时前
.Net Framework 4/C# 集合和索引器
c#
布伦鸽4 小时前
C# WPF 左右布局实现学习笔记(1)
笔记·学习·c#·wpf
InCerry5 小时前
C# 模式匹配全解:原理、用法与易错点
c#
IGP95 小时前
20250606-C#知识:List排序
c#·list
老刘忙Giser5 小时前
c# List<string>.Add(s) 报错:UnsupportedOperationException
开发语言·c#
The Future is mine6 小时前
在.NET Core控制器中获取AJAX传递的Body参数
c#·.netcore