Unity 虚拟仿真实验中设计模式的使用 ——命令模式(Command Pattern)

📖 目录

  1. 前言

  2. 什么是命令模式

  3. 案例背景:虚拟仿真实验中的操作管理

  4. 案例效果图(示意)

  5. 代码实现

    • 5.1 命令接口:ICommand

    • 5.2 具体命令类:HeatCommand / CoolCommand

    • 5.3 调用者:CommandInvoker

    • 5.4 接收者:WaterHeater

    • 5.5 UI 控制:按钮触发命令

  6. 运行流程

  7. 注意事项总结

  8. 扩展思考

  9. 总结


1. 前言

在虚拟仿真实验中,实验对象的操作可能需要:

  • 记录操作顺序

  • 撤销/重做操作

  • 队列化操作执行

如果直接在 UI 里写逻辑,操作管理会混乱。

命令模式(Command Pattern) 可以把操作封装成对象,使得操作可 记录、撤销、排队 ,且 调用者与接收者解耦


2. 什么是命令模式

命令模式:将一个请求封装成对象,从而使你可用不同的请求、队列化请求或记录请求日志,以及支持可撤销操作。

优点

  • 解耦调用者和接收者

  • 可以记录、撤销或重做操作

  • 易于扩展新操作


3. 案例背景:虚拟仿真实验中的操作管理

  • 实验对象:水壶

  • 可操作行为:

    1. 加热(HeatCommand)

    2. 冷却(CoolCommand)

  • UI 点击按钮 → 创建命令 → 执行

  • 可以撤销操作 → 返回上一个状态


4. 案例效果图(示意)

cs 复制代码
[加热按钮] → HeatCommand → 水温升高
[冷却按钮] → CoolCommand → 水温下降
[撤销按钮] → 回到上一个状态

5. 代码实现

5.1 命令接口:ICommand

cs 复制代码
public interface ICommand
{
    void Execute();
    void Undo();
}

5.2 具体命令类

HeatCommand

cs 复制代码
using UnityEngine;

public class HeatCommand : ICommand
{
    private WaterHeater receiver;
    private float previousTemp;

    public HeatCommand(WaterHeater receiver)
    {
        this.receiver = receiver;
    }

    public void Execute()
    {
        previousTemp = receiver.Temperature;
        receiver.Heat();
    }

    public void Undo()
    {
        receiver.SetTemperature(previousTemp);
    }
}

CoolCommand

cs 复制代码
using UnityEngine;

public class CoolCommand : ICommand
{
    private WaterHeater receiver;
    private float previousTemp;

    public CoolCommand(WaterHeater receiver)
    {
        this.receiver = receiver;
    }

    public void Execute()
    {
        previousTemp = receiver.Temperature;
        receiver.Cool();
    }

    public void Undo()
    {
        receiver.SetTemperature(previousTemp);
    }
}

5.3 调用者:CommandInvoker

cs 复制代码
using System.Collections.Generic;

public class CommandInvoker
{
    private Stack<ICommand> commandHistory = new Stack<ICommand>();

    public void ExecuteCommand(ICommand command)
    {
        command.Execute();
        commandHistory.Push(command);
    }

    public void Undo()
    {
        if (commandHistory.Count > 0)
        {
            ICommand command = commandHistory.Pop();
            command.Undo();
        }
    }
}

5.4 接收者:WaterHeater

cs 复制代码
using UnityEngine;

public class WaterHeater : MonoBehaviour
{
    public float Temperature { get; private set; } = 20f;

    public void Heat()
    {
        Temperature += 10f;
        Debug.Log($"加热中,温度:{Temperature}℃");
    }

    public void Cool()
    {
        Temperature -= 10f;
        Debug.Log($"冷却中,温度:{Temperature}℃");
    }

    public void SetTemperature(float temp)
    {
        Temperature = temp;
        Debug.Log($"撤销操作,温度恢复:{Temperature}℃");
    }
}

5.5 UI 控制:按钮触发命令

cs 复制代码
using UnityEngine;
using UnityEngine.UI;

public class CommandUI : MonoBehaviour
{
    [SerializeField] private Button heatButton;
    [SerializeField] private Button coolButton;
    [SerializeField] private Button undoButton;
    [SerializeField] private WaterHeater waterHeater;

    private CommandInvoker invoker = new CommandInvoker();

    private void Start()
    {
        heatButton.onClick.AddListener(() =>
        {
            invoker.ExecuteCommand(new HeatCommand(waterHeater));
        });

        coolButton.onClick.AddListener(() =>
        {
            invoker.ExecuteCommand(new CoolCommand(waterHeater));
        });

        undoButton.onClick.AddListener(() =>
        {
            invoker.Undo();
        });
    }
}

6. 运行流程

  1. 玩家点击 加热按钮 → 创建 HeatCommand → 执行 → 温度升高

  2. 玩家点击 冷却按钮 → 创建 CoolCommand → 执行 → 温度下降

  3. 玩家点击 撤销按钮 → 弹出栈顶命令 → 调用 Undo → 恢复上一次状态


7. 注意事项总结

  • 撤销操作需记录状态:在 Execute 前保存当前状态

  • 命令对象独立:命令类只调用接收者方法,不处理 UI

  • 调用者解耦接收者:UI 或系统只与 CommandInvoker 交互


8. 扩展思考

  • 可以结合 对象池模式,回收命令对象,减少 GC

  • 可以记录操作序列 → 实现实验回放

  • 可以结合 观察者模式 → UI 或日志自动更新


9. 总结

通过这个虚拟仿真案例,你学会了:

  • 使用 命令模式 封装实验操作

  • 支持撤销操作,操作管理清晰

  • 调用者和接收者解耦,易于扩展新操作

👉 命令模式在虚拟实验系统中,非常适合操作管理、撤销与回放功能,提升实验交互体验。

相关推荐
大飞pkz2 小时前
【设计模式】桥接模式
开发语言·设计模式·c#·桥接模式
BeyondCode程序员5 小时前
设计原则讲解与业务实践
设计模式·架构
青草地溪水旁5 小时前
设计模式(C++)详解——迭代器模式(1)
c++·设计模式·迭代器模式
青草地溪水旁5 小时前
设计模式(C++)详解——迭代器模式(2)
java·c++·设计模式·迭代器模式
苍老流年5 小时前
1. 设计模式--工厂方法模式
设计模式·工厂方法模式
PaoloBanchero6 小时前
Unity 虚拟仿真实验中设计模式的使用 ——策略模式(Strategy Pattern)
unity·设计模式·策略模式
PaoloBanchero6 小时前
Unity 虚拟仿真实验中设计模式的使用 —— 观察者模式(Observer Pattern)
观察者模式·unity·设计模式
Mr_WangAndy6 小时前
C++设计模式_创建型模式_单件模式
c++·单例模式·设计模式
笨手笨脚の6 小时前
设计模式-享元模式
设计模式·享元模式·结构型设计模式·设计模式之美