在Unity开发中, 装饰器模式 (Decorator Pattern) 用于动态地给对象添加额外功能, 同时不改变其原始结构. 它比继承更灵活 ——— 可以通过”包装”的上市组合多个功能, 而非通过复杂的继承链堆叠功能, 避免”类爆炸”问题.
 

举个具体场景: 角色攻击强化系统

假设你的游戏中有一个基础战士角色, 他的基础攻击是”物理伤害”. 随着游戏推进, 角色可能获得各种强化效果:
  • 火焰附魔(攻击附加火焰伤害)
  • 暴击效果(有概率造成双倍伤害)
  • 吸血效果(攻击时恢复生命值)
 
如果用继承实现(如 WarriorWithfire \ WarriorWithFireAndCrit …), 每增加一种效果组合就要新增一个类, 扩展性极差. 装饰器模式可以解决这个问题: 用”装饰器”包裹基础角色, 动态叠加效果.
 

装饰器模式的核心角色

  1. 抽象组件(Component): 定义对象的核心行为接口(如:”攻击”)
  1. 具体组件(ConcreteComponent): 实现抽象组件的基础对象(如”基础战士”)
  1. 抽象装饰器(Decorator): 实现抽象组件, 同时持有一个抽象组件的引用(用于”包装”其他组件).
  1. 具体装饰器(ConcreteDecorator): 继承抽象装饰器, 添加具体额外功能(如”火焰伤害””暴击”).
 

代码实现步骤

  1. 定义抽象组件(核心行为接口)
先定义角色攻击的核心接口, 规定所有”可攻击对象”必须实现 Attack() 方法:
 
  1. 实现具体组件(基础角色)
这是被装饰的”基础对象”, 实现最原始的攻击逻辑:
 
3.实现抽象装饰器(包装基础)
抽象装饰器需要”包装”其他 IAttackable 对象(可以是基础角色, 也可以是其他装饰器), 并实现 IAttackable 接口:
 
  1. 实现具体装饰器(添加额外功能)
每个具体装饰器负责添加一种额外效果, 在调用被装饰对象的 Attack() 之前/之后执行自己的逻辑:
 
  1. 客户端使用(动态组合效果)
在游戏逻辑中, 通过 “嵌套包装” 的方式给角色动态添加效果, 组合顺序不影响最终功能:
 

装饰器模式的核心优势

  1. 动态组合功能: 可以在运行时给对象添加/移除功能(比如战斗中临时获得的buff), 无需修改原始对象代码.
  1. 避免类爆炸: 如果用继承实现 “火焰 + 暴击 + 吸血”, 需要 WarriorWithFire \ WarriorWithFireAndCrit 等多个类; 用装饰器只需 3个装饰器, 且可任意组合(如”暴击 + 吸血” “火焰 + 吸血”等).
  1. 单一职责: 每个装饰器只负责一种额外功能(火焰\暴击\吸血), 修改一个功能也不会影响其他功能.
 

在Unity中其他应用场景

  • 道具系统: 角色使用”速度药水””力量药水”等, 每种药水通过装饰器动态添加属性加成, 效果可叠加或过期移除.
  • 武器附魔: 一把剑可以同时附魔 “冰””雷””毒”, 每种附魔是一个装饰器, 攻击时依次触发效果.
  • UI特效: 给按钮添加”点击音效””缩放动画””粒子特效”, 每个特效用装饰器包装, 可灵活组合.
 

装饰器模式 vs 继承

  • 继承: 静态地在编译时确定功能, 新增组合需要新增子类, 灵活性差.
  • 装饰器: 动态地在运行时组合功能, 通过包装实现, 无需新增子类, 扩展性强.
 
装饰器模式就像”叠buff” ——— 基础角色是”白板”, 每个buff是一个装饰器, 叠多少层\叠什么buff, 完全由你动态决定.