Unity 常用面向对象设计模式系列(10):组合模式(Composite)
在 Unity 中,有大量树形结构的数据与对象:UI 元素的父子层级、技能树、场景中的分层 GameObject、对话系统的节点图……如果把每个节点与其子节点的操作拆开写,代码会充斥着递归与遍历逻辑,难以维护。组合模式(Composite Pattern)提供了一种“统一对待单个对象和组合对象”的方式,让客户端无需区分叶子节点与容器节点,直接调用相同接口完成递归操作。
加载过慢请开启缓存 浏览器默认开启
在 Unity 中,有大量树形结构的数据与对象:UI 元素的父子层级、技能树、场景中的分层 GameObject、对话系统的节点图……如果把每个节点与其子节点的操作拆开写,代码会充斥着递归与遍历逻辑,难以维护。组合模式(Composite Pattern)提供了一种“统一对待单个对象和组合对象”的方式,让客户端无需区分叶子节点与容器节点,直接调用相同接口完成递归操作。
在 Unity 中,不同对象往往需要在运行时根据场景、配置或玩家选择来切换不同算法或行为——比如 AI 的寻路算法、角色的攻击方式、技能的释放逻辑等。若把这些差异化代码散落在同一个类里,用大量 if/else 或 switch 分支,不仅难以维护,还会违背“对扩展开放、对修改关闭”的原则。策略模式(Strategy Pattern)通过将一系列可互换的算法封装到独立策略类中,让客户端在运行时自由选择或切换策略,实现了行为的解耦与灵活扩展。
在游戏中,角色常有多种行为状态:站立、行走、跳跃、攻击、受击、死亡……如果把所有状态逻辑堆在一个 Update() 里,用大量 if/else 或 switch 分支,不仅会导致代码臃肿难以维护,还容易引入状态切换错误。状态模式(State Pattern)通过将每个状态封装成独立类,并由一个 Context 管理当前状态与转换逻辑
在游戏开发中,操作往往来源于输入设备、AI 决策或网络指令。将这些操作逻辑直接写在 Update() 或各组件里,会导致代码膨胀、耦合度高,且无法支持撤销/重做、宏命令、操作录制/回放等高级功能。命令模式(Command Pattern)将“请求”封装为对象,使得调用者(Invoker)与执行者(Receiver)解耦,并能轻松支持队列、撤销、重做、日志、宏等功能。
在游戏开发中,各种系统之间常常需要松耦合的状态通知:角色受伤后要更新 UI、血条;玩家拾取道具后要触发音效、成就系统;关卡结束时要弹出结算面板……如果直接在各个模块里硬编码依赖,代码会迅速陷入交叉引用的“蜘蛛网”,难以维护与扩展。观察者模式(Observer / Event)提供了一种一对多的通知机制,让“被观察者”在自身状态变化时自动广播事件,所有“观察者”自行订阅、响应,解耦了模块间的直接依赖。
在 Unity 项目中,我们经常需要集成各种第三方 SDK(Analytics、IAP、广告)、或针对不同平台(Android/iOS/PC)使用不同的底层 API。直接在业务代码中写大量 #if UNITY_ANDROID、#if UNITY_IOS、或直接调用 SDK 接口,不仅让代码变得凌乱,还给测试和维护带来巨大成本。适配器模式(Adapter Pattern)通过在客户端与具体实现之间引入一个“中间层”,将各个差异化接口统一成业务期望的抽象接口,大幅降低耦合,提高可维护性和可测试性。
在 Unity 项目中,频繁的 Instantiate 和 Destroy 操作会带来严重的性能开销和 GC 压力,尤其是在子弹特效、爆炸效果、敌人复活等高频率创建/销毁场景下。对象池模式(Object Pool)通过重用对象,避免重复分配和销毁,能显著提升帧率稳定性和内存效率。
在 Unity 项目中,经常会遇到“何时实例化哪个类”的问题——不论是玩家释放不同类型的技能、动态生成 UI 面板,还是在关卡中孵化各式怪物,如果把所有 new 或 Instantiate 逻辑散落在业务代码里,不仅耦合度高,而且扩展新类型时必须修改原有代码,违背“对扩展开放、对修改关闭”的开闭原则。工厂模式(Factory Pattern)通过封装创建逻辑,让客户端只依赖抽象工厂或简单的工厂方法,极大地提高了系统的灵活度与可维护性。
游戏开发中,经常需要一个全局唯一的“管理器”来协调各个子系统——如游戏状态、音频系统、配置表加载等。单例模式(Singleton)就是用来保证类在运行时只有一个实例,并提供一个全局访问点。在 Unity 中,常见的 GameManager、AudioManager、UIManager 等都采用单例模式。但在引擎环境下,单例的生命周期、场景切换、测试与依赖管理都存在许多坑。本篇将从原理到实战、变种与陷阱,一步步剖析 Unity 单例模式的正确姿势。
在 Unity 引擎中,随着项目规模和复杂度的提升,代码组织方式对可维护性、可扩展性和性能的影响日益显著。设计模式提供了一套行之有效的架构思路,帮助我们在持续迭代中保持代码清晰、职责分明、耦合度低。本系列博客共分八篇,第一篇为总览,介绍 创建型、结构型、行为型 三大类常用模式,以及它们在 Unity 中的典型应用场景。