【行为型之责任链模式】游戏开发实战——Unity灵活事件处理系统的架构核心

文章目录

      • ⛓️ 责任链模式(Chain of Responsibility Pattern)深度解析
        • 一、模式本质与核心价值
        • 二、经典UML结构
        • 三、Unity实战代码(伤害处理系统)
          • 1. 定义请求对象与处理接口
          • 2. 实现具体处理者
          • 3. 构建处理链
        • 四、模式进阶技巧
          • 1. 动态重组处理链
          • 2. 条件终止传递
          • 3. 异步处理流程
        • 五、游戏开发典型应用场景
        • 六、性能优化策略
        • 七、模式对比与选择
        • 八、最佳实践原则
        • 九、常见问题解决方案

⛓️ 责任链模式(Chain of Responsibility Pattern)深度解析

——以Unity实现动态伤害处理灵活事件系统为核心案例


一、模式本质与核心价值

核心目标
解耦请求发送者与接收者,形成处理链
动态调整处理流程,支持运行时修改处理顺序
灵活扩展新处理逻辑,符合开闭原则

关键术语

  • Handler(处理者接口):定义处理请求的方法和后续处理器
  • ConcreteHandler(具体处理者):实现具体处理逻辑
  • Request(请求):封装请求数据的对象

数学表达
处理链H = h₁ → h₂ → … → hₙ
请求Q的处理结果:H(Q) = h₁(h₂(…hₙ(Q)…)


二、经典UML结构
next
next
«interface»
IDamageHandler
+SetNext(handler: IDamageHandler)
+HandleDamage(request: DamageRequest)
ArmorHandler
+HandleDamage()
ShieldHandler
+HandleDamage()
HealthHandler
+HandleDamage()

三、Unity实战代码(伤害处理系统)
1. 定义请求对象与处理接口
public class DamageRequest {
    public float RawDamage;
    public DamageType Type;
    public GameObject Target;
    public GameObject Attacker;
}

public interface IDamageHandler {
    IDamageHandler SetNext(IDamageHandler handler);
    void HandleDamage(DamageRequest request);
}
2. 实现具体处理者
public abstract class AbstractDamageHandler : MonoBehaviour, IDamageHandler {
    private IDamageHandler _next;
    
    public IDamageHandler SetNext(IDamageHandler handler) {
        _next = handler;
        return handler;
    }

    public virtual void HandleDamage(DamageRequest request) {
        if(_next != null) {
            _next.HandleDamage(request);
        }
    }
}

public class ArmorHandler : AbstractDamageHandler {
    [SerializeField] private float _armor = 50;
    
    public override void HandleDamage(DamageRequest request) {
        float mitigated = Mathf.Max(request.RawDamage - _armor, 0);
        request.RawDamage = mitigated;
        base.HandleDamage(request);
    }
}

public class ElementalResistanceHandler : AbstractDamageHandler {
    [SerializeField] private DamageType _resistanceType;
    [SerializeField] private float _resistance = 0.3f;
    
    public override void HandleDamage(DamageRequest request) {
        if(request.Type == _resistanceType) {
            request.RawDamage *= (1 - _resistance);
        }
        base.HandleDamage(request);
    }
}
3. 构建处理链
public class DamageSystem : MonoBehaviour {
    void Start() {
        var armor = GetComponent<ArmorHandler>();
        var elementResist = GetComponent<ElementalResistanceHandler>();
        var finalHandler = GetComponent<HealthHandler>();
        
        armor.SetNext(elementResist).SetNext(finalHandler);
    }
    
    public void ApplyDamage(DamageRequest request) {
        GetComponent<ArmorHandler>().HandleDamage(request);
    }
}

四、模式进阶技巧
1. 动态重组处理链
public class DynamicHandlerChain : MonoBehaviour {
    private List<IDamageHandler> _handlers = new();
    
    public void AddHandler(IDamageHandler handler) {
        if(_handlers.Count > 0) {
            _handlers.Last().SetNext(handler);
        }
        _handlers.Add(handler);
    }
}
2. 条件终止传递
public class InvincibilityHandler : AbstractDamageHandler {
    public override void HandleDamage(DamageRequest request) {
        if(request.Target.CompareTag("Invincible")) {
            request.RawDamage = 0;
            return; // 终止传递
        }
        base.HandleDamage(request);
    }
}
3. 异步处理流程
public class AsyncDamageHandler : AbstractDamageHandler {
    public override void HandleDamage(DamageRequest request) {
        StartCoroutine(HandleAsync(request));
    }
    
    private IEnumerator HandleAsync(DamageRequest request) {
        yield return new WaitForSeconds(0.5f);
        base.HandleDamage(request);
    }
}

五、游戏开发典型应用场景
  1. 输入处理系统

    public class InputHandlerChain {
        private List<IInputHandler> _handlers = new();
        
        public void ProcessInput(InputEvent e) {
            foreach(var handler in _handlers) {
                if(handler.Handle(e)) break;
            }
        }
    }
    
  2. 对话系统分支处理

    public class DialogueHandler : MonoBehaviour {
        private IDialogueHandler _chain;
        
        public void HandleDialogue(DialogueNode node) {
            _chain.Handle(node);
        }
    }
    
  3. 成就解锁流程

    public class AchievementUnlockChain {
        public void CheckUnlocks(PlayerStats stats) {
            _firstHandler.Handle(stats);
        }
    }
    
  4. 任务条件验证

    public class QuestValidator {
        private List<IConditionHandler> _handlers = new();
        
        public bool ValidateQuest(Quest q) {
            foreach(var handler in _handlers) {
                if(!handler.Check(q)) return false;
            }
            return true;
        }
    }
    

六、性能优化策略
策略 实现方式 适用场景
缓存处理器 预先生成处理链 固定处理流程
短路返回 及时终止处理链 存在终止条件
批处理 合并同类请求 高频请求场景
分帧处理 使用协程分帧处理 长处理链条

七、模式对比与选择
维度 责任链模式 命令模式
关注点 请求传递流程 请求封装
灵活性 动态调整链条 固定执行
典型场景 多条件处理 撤销/重做
关系方向 单向传递 双向交互

八、最佳实践原则
  1. 控制链条长度:建议不超过7个处理节点
  2. 明确终止条件:避免无限循环
  3. 统一接口规范
    public interface IHandler<T> {
        bool Handle(T request);
    }
    
  4. 异常处理机制
    public void HandleDamage(DamageRequest request) {
        try {
            // 处理逻辑
        } catch(Exception e) {
            Debug.LogError($"处理链异常:{e.Message}");
        }
    }
    

九、常见问题解决方案

Q1:如何处理循环链?
→ 实现环路检测机制

public class SafeHandler : AbstractDamageHandler {
    private HashSet<DamageRequest> _processing = new();
    
    public override void HandleDamage(DamageRequest request) {
        if(_processing.Contains(request)) return;
        _processing.Add(request);
        base.HandleDamage(request);
        _processing.Remove(request);
    }
}

Q2:如何调试复杂处理流程?
→ 实现处理追踪器

public class DebugHandler : AbstractDamageHandler {
    public override void HandleDamage(DamageRequest request) {
        Debug.Log($"[{Time.time}] 经过处理器:{GetType().Name}");
        base.HandleDamage(request);
    }
}

Q3:如何优化处理顺序?
→ 实现优先级系统

public class PriorityHandler : IComparable<PriorityHandler> {
    public int Priority;
    
    public int CompareTo(PriorityHandler other) {
        return Priority.CompareTo(other.Priority);
    }
}

上一篇 【结构型之代理模式】游戏开发实战——Unity智能资源加载与安全系统的架构密码
下一篇 【行为型之命令模式】游戏开发实战——Unity可撤销系统与高级输入管理的架构秘钥

你可能感兴趣的:(【行为型之责任链模式】游戏开发实战——Unity灵活事件处理系统的架构核心)