【行为型之模板方法模式】游戏开发实战——Unity标准化流程与可扩展架构的核心实现

文章目录

      • 模板方法模式(Template Method Pattern)深度解析
        • 一、模式本质与核心价值
        • 二、经典UML结构
        • 三、Unity实战代码(关卡流程系统)
          • 1. 定义抽象模板类
          • 2. 实现具体子类
          • 3. 客户端使用
        • 四、模式进阶技巧
          • 1. 钩子方法(Hook)
          • 2. 阶段状态控制
          • 3. 异步加载优化
        • 五、游戏开发典型应用场景
        • 六、性能优化策略
        • 七、模式对比与选择
        • 八、最佳实践原则
        • 九、常见问题解决方案

模板方法模式(Template Method Pattern)深度解析

——以Unity实现标准化游戏流程灵活AI行为框架为核心案例


一、模式本质与核心价值

核心目标
定义算法骨架,将某些步骤延迟到子类实现
复用算法结构,确保流程一致性
避免代码冗余,通过继承实现差异化

关键术语

  • AbstractClass(抽象类):定义模板方法和抽象操作
  • ConcreteClass(具体子类):实现抽象操作的具体逻辑
  • Template Method(模板方法):定义算法的步骤序列

数学表达
设算法流程为:A → B → C → D
模板方法确保所有子类遵循此流程,但允许自定义B和C的实现


二、经典UML结构
«abstract»
GameLevel
+LoadLevel()
+Initialize()
+StartLevel()
+EndLevel()
+PlayLevel()
BossLevel
+Initialize()
+StartLevel()
+EndLevel()
PuzzleLevel
+Initialize()
+StartLevel()
+EndLevel()

三、Unity实战代码(关卡流程系统)
1. 定义抽象模板类
public abstract class GameLevel : MonoBehaviour {
    // 模板方法(不可重写)
    public sealed override IEnumerator PlayLevel() {
        LoadLevelAssets();
        yield return InitializeLevel();
        yield return StartLevelCore();
        yield return EndLevelProcess();
        Cleanup();
    }

    // 具体步骤(部分有默认实现)
    protected virtual void LoadLevelAssets() {
        Debug.Log("加载基础资源...");
        // 加载公共资源逻辑
    }

    protected abstract IEnumerator InitializeLevel();
    protected abstract IEnumerator StartLevelCore();
    
    protected virtual IEnumerator EndLevelProcess() {
        Debug.Log("执行默认结算流程...");
        yield return new WaitForSeconds(1);
    }

    protected virtual void Cleanup() {
        Debug.Log("清理临时资源...");
    }
}
2. 实现具体子类
// BOSS关卡
public class BossLevel : GameLevel {
    [SerializeField] private GameObject _bossPrefab;
    
    protected override IEnumerator InitializeLevel() {
        Debug.Log("生成BOSS...");
        Instantiate(_bossPrefab);
        yield return new WaitForSeconds(2);
    }

    protected override IEnumerator StartLevelCore() {
        Debug.Log("开始BOSS战!");
        // BOSS战斗逻辑
        yield return new WaitUntil(() => !IsBossAlive());
    }
    
    private bool IsBossAlive() {
        // 检测BOSS存活状态
        return true;
    }
}

// 解谜关卡
public class PuzzleLevel : GameLevel {
    [SerializeField] private PuzzleSystem _puzzle;
    
    protected override IEnumerator InitializeLevel() {
        Debug.Log("初始化谜题组件...");
        _puzzle.ResetPuzzle();
        yield return null;
    }

    protected override IEnumerator StartLevelCore() {
        Debug.Log("启动谜题...");
        yield return new WaitUntil(() => _puzzle.IsSolved);
    }
    
    protected override IEnumerator EndLevelProcess() {
        yield return base.EndLevelProcess();
        Debug.Log("展示解谜奖励...");
        yield return new WaitForSeconds(2);
    }
}
3. 客户端使用
public class LevelManager : MonoBehaviour {
    [SerializeField] private GameLevel _currentLevel;
    
    void Start() {
        StartCoroutine(PlayCurrentLevel());
    }
    
    private IEnumerator PlayCurrentLevel() {
        yield return _currentLevel.PlayLevel();
        Debug.Log("关卡流程结束!");
    }
    
    public void SwitchLevel(GameLevel newLevel) {
        _currentLevel = newLevel;
        StartCoroutine(PlayCurrentLevel());
    }
}

四、模式进阶技巧
1. 钩子方法(Hook)
protected virtual bool ShouldSkipIntro() => false;

public sealed override IEnumerator PlayLevel() {
    if(!ShouldSkipIntro()) {
        yield return PlayIntroAnimation();
    }
    // 后续流程...
}
2. 阶段状态控制
public abstract class GameLevel : MonoBehaviour {
    private enum LevelState { Loading, Initializing, Running, Ending }
    private LevelState _currentState;
    
    protected void SetState(LevelState newState) {
        _currentState = newState;
        OnStateChanged?.Invoke(newState);
    }
    
    public event Action<LevelState> OnStateChanged;
}
3. 异步加载优化
protected virtual async Task LoadLevelAssetsAsync() {
    var loadOp = Addressables.LoadAssetsAsync<GameObject>("LevelBaseAssets");
    await loadOp.Task;
    Debug.Log($"已加载 {loadOp.Result.Count} 个基础资源");
}

五、游戏开发典型应用场景
  1. 角色行为模板

    public abstract class CharacterBehavior {
        public void ExecuteDailyRoutine() {
            WakeUp();
            Eat();
            Work();
            Sleep();
        }
        protected abstract void Work();
        // 其他步骤可有默认实现...
    }
    
  2. 技能释放流程

    public abstract class SkillBase {
        public void Cast() {
            PlayCastAnimation();
            ApplyPreEffects();
            ExecuteCoreLogic();
            ApplyPostEffects();
        }
        protected abstract void ExecuteCoreLogic();
    }
    
  3. UI面板通用流程

    public abstract class UIPanel : MonoBehaviour {
        public IEnumerator Show() {
            PreShowSetup();
            yield return PlayShowAnimation();
            PostShowInitialize();
        }
        protected virtual void PreShowSetup() { /* 默认空实现 */ }
        protected abstract IEnumerator PlayShowAnimation();
    }
    
  4. 敌人生成系统

    public abstract class EnemySpawner {
        public void SpawnWave() {
            PreSpawnCheck();
            CalculateSpawnPoints();
            SpawnEnemies();
            PostSpawnActions();
        }
        protected abstract void SpawnEnemies();
    }
    

六、性能优化策略
策略 实现方式 适用场景
预编译模板 使用泛型模板类 高频实例化场景
步骤缓存 缓存重复计算结果 复杂初始化流程
分帧执行 使用协程分步骤执行 长耗时流程
资源预加载 提前加载共用资源 资源密集型关卡

七、模式对比与选择
维度 模板方法模式 策略模式
代码复用方式 继承 组合
灵活性 修改需要继承 运行时动态切换
适用场景 固定流程算法 可替换算法模块
扩展方向 垂直扩展(子类化) 水平扩展(新增策略)

八、最佳实践原则
  1. 模板方法密封:防止子类修改算法骨架
    public sealed override void ExecuteProcess() { /* ... */ }
    
  2. 合理使用虚方法:提供默认实现而非强制重写
  3. 控制继承层级:建议不超过3层继承
  4. 文档注释:明确说明各步骤职责
    /// 
    /// 初始化关卡核心元素,必须由子类实现
    /// 
    protected abstract void InitializeCore();
    

九、常见问题解决方案

Q1:如何避免过度继承?
→ 使用组合+模板方法混合模式

public class LevelProcessor {
    private ILevelInitializer _initializer;
    private ILevelFinalizer _finalizer;
    
    public void ExecuteProcess() {
        LoadCommonAssets();
        _initializer.Initialize();
        RunCoreLogic();
        _finalizer.Finalize();
    }
}

Q2:如何处理跨步骤状态共享?
→ 使用上下文对象传递数据

public class LevelContext {
    public int Score;
    public float TimeSpent;
    public List<Enemy> AliveEnemies = new();
}

protected abstract void ExecuteCore(LevelContext context);

Q3:如何调试多层级模板?
→ 实现步骤追踪器

public abstract class DebuggableTemplate : MonoBehaviour {
    private void LogStep(string message) {
        Debug.Log($"[{Time.time:F2}] {GetType().Name} - {message}");
    }
    
    protected sealed override void LoadResources() {
        LogStep("开始加载资源");
        base.LoadResources();
        LogStep("资源加载完成");
    }
}

上一篇 【行为型之策略模式】游戏开发实战——Unity灵活算法架构的核心实现策略
下一篇 【行为型之访问者模式】游戏开发实战——Unity灵活数据操作与跨系统交互的架构秘诀

你可能感兴趣的:(设计模式,模板方法模式,unity,c#,设计模式)