文章目錄
- 🔄 迭代器模式(Iterator Pattern)深度解析
- 一、模式本質與核心價值
- 二、經典UML結構
- 三、Unity實戰代碼(背包系統遍歷)
- 1. 定義迭代器與聚合接口
- 2. 實現具體聚合類(背包物品集合)
- 3. 實現具體迭代器
- 4. 客戶端使用
- 四、模式進階技巧
- 1. 過濾迭代器(按類型遍歷)
- 2. 協程分幀遍歷
- 3. 雙向迭代器
- 五、游戲開發典型應用場景
- 六、性能優化策略
- 七、模式對比與選擇
- 八、最佳實踐原則
- 九、常見問題解決方案
🔄 迭代器模式(Iterator Pattern)深度解析
——以Unity實現高效集合遍歷與動態場景管理為核心案例
一、模式本質與核心價值
核心目標:
? 統一集合遍歷接口,無需暴露內部數據結構
? 支持多種遍歷方式(順序、逆序、過濾等)
? 解耦集合結構與遍歷算法,提升代碼擴展性
關鍵術語:
- Iterator(迭代器接口):定義遍歷操作(Next、HasNext等)
- ConcreteIterator(具體迭代器):實現特定遍歷邏輯
- Aggregate(聚合接口):定義創建迭代器的方法
- ConcreteAggregate(具體聚合):實現集合數據結構
數學表達:
設集合C有元素{e?, e?, …, e?},迭代器I滿足:
I? → e? → e? → … → e?
二、經典UML結構
三、Unity實戰代碼(背包系統遍歷)
1. 定義迭代器與聚合接口
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. 實現具體聚合類(背包物品集合)
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. 實現具體迭代器
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. 客戶端使用
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. 過濾迭代器(按類型遍歷)
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. 協程分幀遍歷
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. 雙向迭代器
public interface IBidirectionalIterator<T> : IIterator<T> {bool HasPrevious();T Previous();
}public class InventoryBidirectionalIterator : IBidirectionalIterator<Item> {// 實現前后遍歷邏輯
}
五、游戲開發典型應用場景
-
場景對象管理
public class SceneObjectManager : IAggregate<GameObject> {private List<GameObject> _objects = new();public IIterator<GameObject> CreateIterator() => new SceneObjectIterator(this); }
-
技能效果鏈
public class SkillEffectChain : IAggregate<IEffect> {public IIterator<IEffect> CreateReverseIterator() {return new ReverseEffectIterator(this);} }
-
AI決策評估
public class AIEvaluator {public void EvaluateAll(IIterator<AICondition> conditions) {while(conditions.HasNext()) {var condition = conditions.Next();condition.Evaluate();}} }
-
動態生成系統
public class WorldGenerator {public void GenerateChunks(IIterator<Vector3> positionIterator) {while(positionIterator.HasNext()) {GenerateChunkAt(positionIterator.Next());}} }
六、性能優化策略
策略 | 實現方式 | 適用場景 |
---|---|---|
批處理迭代 | 每次處理多個元素 | 大規模數據集 |
緩存迭代器 | 復用迭代器實例 | 頻繁遍歷操作 |
惰性求值 | 需要時再計算元素 | 復雜對象集合 |
空間分區 | 結合四叉樹/八叉樹 | 3D場景遍歷 |
七、模式對比與選擇
維度 | 迭代器模式 | 訪問者模式 |
---|---|---|
關注點 | 遍歷機制 | 數據操作 |
擴展性 | 新增迭代方式 | 新增操作類型 |
數據結構耦合 | 低耦合 | 需要接受訪問者接口 |
典型場景 | 集合遍歷 | 復雜數據結構操作 |
八、最佳實踐原則
- 單一職責原則:迭代器只關注遍歷邏輯
- 不可變快照:在迭代過程中防止集合修改
public class SnapshotIterator<T> : IIterator<T> {private readonly T[] _snapshot;// 基于快照的迭代實現... }
- 異常處理:處理邊界條件
public T Next() {if(!HasNext()) throw new InvalidOperationException("No more elements");// ... }
- 資源釋放:實現IDisposable接口
public class FileLineIterator : IIterator<string>, IDisposable {private StreamReader _reader;public void Dispose() => _reader?.Dispose(); }
九、常見問題解決方案
Q1:如何避免遍歷時集合被修改?
→ 使用讀寫鎖或副本迭代
public class ThreadSafeIterator<T> : IIterator<T> {private ReaderWriterLockSlim _lock;// 在Next/HasNext中加讀鎖...
}
Q2:如何實現復雜條件過濾?
→ 使用組合過濾器
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:如何優化大型場景遍歷性能?
→ 實現空間分區迭代器
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復雜系統協調與通信架構的核心秘訣