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

news2025/5/16 19:22:06

文章目录

      • 🔄 迭代器模式(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结构
creates
«interface»
IIterator
+HasNext() : bool
+Next() : object
InventoryIterator
-_items: Item[]
-_index: int
+HasNext()
+Next()
«interface»
IAggregate
+CreateIterator() : IIterator
Inventory
-_items: Item[]
+CreateIterator()

三、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> {
    // 实现前后遍历逻辑
}

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

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

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

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

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

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

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

八、最佳实践原则
  1. 单一职责原则:迭代器只关注遍历逻辑
  2. 不可变快照:在迭代过程中防止集合修改
    public class SnapshotIterator<T> : IIterator<T> {
        private readonly T[] _snapshot;
        // 基于快照的迭代实现...
    }
    
  3. 异常处理:处理边界条件
    public T Next() {
        if(!HasNext()) throw new InvalidOperationException("No more elements");
        // ...
    }
    
  4. 资源释放:实现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复杂系统协调与通信架构的核心秘诀

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2377091.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vuetify框架使用(一)之v-snackbar 组件封装及全局使用

说明&#xff1a;v-snackbar 组件适用于统一管理消息提示框(操作反馈的提示) 看效果&#xff1a; 1、在状态管理中创建文件&#xff0c;统一管理 // stores/snackbar.js /*** 统一管理消息提示框(操作反馈的提示)*/import { defineStore } from pinia; // 消息类型 export co…

FPGA: UltraScale+ bitslip实现(方案+代码)

收获 一晃五年~ 五年前那个夏夜&#xff0c;我对着泛蓝的屏幕敲下《给十年后的自己》&#xff0c;在2020年的疫情迷雾中编织着对未来的想象。此刻回望&#xff0c;第四届集创赛的参赛编号仍清晰如昨&#xff0c;而那个在家熬夜焊电路板的"不眠者"&#xff0c;现在…

【SpeechLMs】语音大型语言模型综述《A Survey on Speech Large Language Models》

摘要 大型语言模型 (LLM) 表现出强大的上下文理解能力和显著的多任务性能。 因此&#xff0c;研究人员一直在寻求将 LLM 整合到更广泛的语音语言理解 (SLU) 领域。 与传统方法不同&#xff0c;传统方法是将 LLM 级联以处理自动语音识别 (ASR) 生成的文本&#xff0c;而新方法则…

吴恩达机器学习笔记:特征与多项式回归

1.特征和多项式回归 如房价预测问题&#xff0c; ℎθ (x) θ0 θ1 frontage θ2 deptℎ x1 frontage&#xff08;临街宽度&#xff09;&#xff0c;x2 deptℎ&#xff08;纵向深度&#xff09;&#xff0c;x frontage ∗ deptℎ area &#xff08;面积&#xff09;…

LangChain4j正式发布-简化将 LLM 集成到 Java 应用程序过程

LangChain4j 的目标是简化将 LLM 集成到 Java 应用程序中的过程。 官网地址 源码地址 开源协议&#xff1a;Apache License 2.0 实现方法 统一 API&#xff1a;LLM 提供程序&#xff08;如 OpenAI 或 Google Vertex AI&#xff09;和嵌入&#xff08;矢量&#xff09;存储…

【C++】汇编角度分析栈攻击

栈攻击 介绍原理示例代码汇编分析 介绍原理 核心原理是通过 缓冲区溢出&#xff08;Buffer Overflow&#xff09; 等漏洞&#xff0c;覆盖栈上的关键数据&#xff08;如返回地址、函数指针&#xff09;&#xff0c;从而改变程序执行流程&#xff1b; 在 C 中&#xff0c;每个…

Vue 3 打开 el-dialog 时使 el-input 获取焦点

运行代码&#xff1a;https://andi.cn/page/622178.html 效果&#xff1a;

C++23 views::repeat (P2474R2) 深入解析

文章目录 引言C20 Ranges库回顾什么是Rangesstd::views的作用 views::repeat概述基本概念原型定义工作原理应用场景初始化容器模拟测试数据 总结 引言 在C的发展历程中&#xff0c;每一个新版本都会带来一系列令人期待的新特性&#xff0c;这些特性不仅提升了语言的性能和表达…

OpenCv高阶(4.0)——案例:海报的透视变换

文章目录 前言一、工具函数模块1.1 图像显示函数1.2 保持宽高比的缩放函数1.3 坐标点排序函数 二、透视变换核心模块2.1 四点透视变换实现 三、主流程技术分解3.1 图像预处理3.2 轮廓检测流程3.3 最大轮廓处理 四、后处理技术4.1 透视变换4.2 形态学处理 五、完整代码总结 前言…

光谱相机的图像预处理技术

光谱相机的图像预处理技术旨在消除噪声、增强有效信息&#xff0c;为后续分析提供高质量数据。 一、预处理流程与技术要点 ‌辐射校正‌ ‌辐射定标‌&#xff1a;将图像灰度值转换为绝对辐射亮度&#xff0c;常用反射率法、辐亮度法和辐照度法消除传感器响应差异&#xff0…

k8s监控方案实践补充(一):部署Metrics Server实现kubectl top和HPA支持

k8s监控方案实践补充&#xff08;一&#xff09;&#xff1a;部署Metrics Server实现kubectl top和HPA支持 文章目录 k8s监控方案实践补充&#xff08;一&#xff09;&#xff1a;部署Metrics Server实现kubectl top和HPA支持一、Metrics Server简介二、Metrics Server实战部署…

嵌入式调试新宠!J-Scope:免费+实时数据可视化,让MCU调试效率飙升!

&#x1f4cc; 痛点直击&#xff1a;调试还在用“断点打印”&#xff1f; 嵌入式开发中&#xff0c;你是否也经历过这些崩溃瞬间&#xff1f; 想实时观察变量变化&#xff0c;代码里插满printf&#xff0c;结果拖垮系统性能&#xff1f; 断点调试打断程序运行&#xff0c;时序…

微信小程序学习之搜索框

1、第一步&#xff0c;我们在index.json中引入vant中的搜索框控件&#xff1a; {"usingComponents": {"van-search": "vant/weapp/search/index"} } 2、第二步&#xff0c;直接在index.wxml中添加布局&#xff1a; <view class"index…

Altium Designer AD如何输出PIN带网络名的PDF装配图

Altium Designer AD如何输出PIN带网络名的PDF装配图 文描述在Altium Designer版本中设置焊盘网络名时遇到的问题&#xff0c;网络名大小不一致&#xff0c;部分PAD的网络名称未显示&#xff0c;可能涉及字符大小设置和版本差异。 参考 1.AD导出PCB装配图 https://blog.csd…

VMware虚拟机 安装 CentOS 7

原文链接: VMware虚拟机 安装 CentOS 7 安装准备 软件: VMware Workstation Pro 17.6.3 镜像: CentOS-7.0-1406-x86_64-DVD.iso 我打包好放这了&#xff0c;VMware 和 CentOS7 &#xff0c;下载即可。 关于VMware Workstation Pro 17.6.3&#xff0c;傻瓜式安装即可。 CentO…

Python训练打卡Day22

复习日&#xff1a; 1.标准化数据&#xff08;聚类前通常需要标准化&#xff09; scaler StandardScaler() X_scaled scaler.fit_transform(X) StandardScaler() &#xff1a;这部分代码调用了 StandardScaler 类的构造函数。在Python中&#xff0c;当你在类名后面加上括号…

Cold Diffusion: Inverting Arbitrary Image Transforms Without Noise论文阅读

冷扩散&#xff1a;无需噪声的任意图像变换反转 摘要 标准扩散模型通常涉及两个核心步骤&#xff1a;图像降质 &#xff08;添加高斯噪声&#xff09;和图像恢复 &#xff08;去噪操作&#xff09;。本文发现&#xff0c;扩散模型的生成能力并不强烈依赖于噪声的选择&#xf…

嵌软面试每日一阅----通信协议篇(二)之TCP

一. TCP和UDP的区别 可靠性 TCP&#xff1a;✅ 可靠传输&#xff08;三次握手 重传机制&#xff09; UDP&#xff1a;❌ 不可靠&#xff08;可能丢包&#xff09; 连接方式 TCP&#xff1a;面向连接&#xff08;需建立/断开连接&#xff09; UDP&#xff1a;无连接&#xff0…

机器学习 --- 模型选择与调优

机器学习 — 模型选择与调优 文章目录 机器学习 --- 模型选择与调优一&#xff0c;交叉验证1.1 保留交叉验证HoldOut1.2 K-折交叉验证(K-fold)1.3 分层k-折交叉验证Stratified k-fold 二&#xff0c;超参数搜索三&#xff0c;鸢尾花数据集示例四&#xff0c;现实世界数据集示例…

AGI大模型(15):向量检索之调用ollama向量数据库

这里介绍将向量模型下载到本地,这里使用ollama,现在本地安装ollama,这里就不过多结束了。直接从下载开始。 1 下载模型 首先搜索模型,这里使用bge-large模型,你可以根据自己的需要修改。 点击进入,复制命令到命令行工具中执行。 安装后查看: 2 代码实现 先下载ollama…