用Unity写设计模式-命令模式

本文介绍了命令模式的基本概念,并通过两个实际案例展示如何实现可撤销操作的计算器和命令管理。第一个案例涉及用户交互和计算器命令的执行与撤销,第二个案例展示了命令与接收者之间的解耦。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

命令模式介绍

命令模式将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象,同时支持可撤消的操作。

命令模式

using UnityEngine;
using System.Collections;

namespace CommandStructure
{
    public class CommandStructure : MonoBehaviour
    {
	    void Start ( )
        {
            // Create receiver, command, and invoker
            Receiver receiver = new Receiver();
            Command command = new ConcreteCommand(receiver);
            Invoker invoker = new Invoker();

            // Set and execute command
            invoker.SetCommand(command);
            invoker.ExecuteCommand();
        }
    }

    /// <summary>
    /// The 'Command' abstract class
    /// </summary>
    abstract class Command
    {
        protected Receiver receiver;

        // Constructor
        public Command(Receiver receiver)
        {
            this.receiver = receiver;
        }

        public abstract void Execute();
    }

    /// <summary>
    /// The 'ConcreteCommand' class
    /// </summary>
    class ConcreteCommand : Command
    {
        // Constructor
        public ConcreteCommand(Receiver receiver) :
          base(receiver)
        {
        }

        public override void Execute()
        {
            receiver.Action();
        }
    }

    /// <summary>
    /// The 'Receiver' class
    /// </summary>
    class Receiver
    {
        public void Action()
        {
          Debug.Log("Called Receiver.Action()");
        }
    }

    /// <summary>
    /// The 'Invoker' class
    /// </summary>
    class Invoker
    {
        private Command _command;

        public void SetCommand(Command command)
        {
            this._command = command;
        }

        public void ExecuteCommand()
        {
            _command.Execute();
        }
    }

}

命令模式案例1

using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

namespace CommandExample1
{
    public class CommandExample1 : MonoBehaviour
    {
	    void Start ( )
        {
            // Create user and let her compute
            User user = new User();

            // User presses calculator buttons
            user.Compute('+', 100);
            user.Compute('-', 50);
            user.Compute('*', 10);
            user.Compute('/', 2);

            // Undo 4 commands
            user.Undo(4);

            // Redo 3 commands
            user.Redo(3);
        }
    }

    /// <summary>
    /// The 'Command' abstract class
    /// </summary>
    abstract class Command
    {
        public abstract void Execute();//执行
        public abstract void UnExecute();//撤销
    }

    /// <summary>
    /// The 'ConcreteCommand' class
    /// </summary>
    class CalculatorCommand : Command
    {
        private char _operator;
        private int _operand;
        private Calculator _calculator;

        // Constructor
        public CalculatorCommand(Calculator calculator,
          char @operator, int operand)
        {
            this._calculator = calculator;
            this._operator = @operator;
            this._operand = operand;
        }

        // Gets operator
        public char Operator
        {
            set { _operator = value; }
        }

        // Get operand
        public int Operand
        {
            set { _operand = value; }
        }

        // Execute new command
        public override void Execute()
        {
            _calculator.Operation(_operator, _operand);
        }

        // Unexecute last command
        public override void UnExecute()
        {
            _calculator.Operation(Undo(_operator), _operand);
        }

        // Returns opposite operator for given operator
        
        private char Undo(char @operator)
        {
            switch (@operator)
            {
                case '+': return '-';
                case '-': return '+';
                case '*': return '/';
                case '/': return '*';
                default:
                    throw new
            ArgumentException("@operator");
            }
        }
    }

    /// <summary>
    /// The 'Receiver' class
    /// 计算器类
    /// </summary>
    class Calculator
    {
        private int _curr = 0;

        /// <summary>
        /// 运算
        /// </summary>
        /// <param name="operator">运算符</param>
        /// <param name="operand">操作数</param>
        public void Operation(char @operator, int operand)
        {
            switch (@operator)
            {
                case '+': _curr += operand; break;
                case '-': _curr -= operand; break;
                case '*': _curr *= operand; break;
                case '/': _curr /= operand; break;
            }
            Debug.Log("Current value = " + _curr+ " ( following "+ @operator+operand+" )");
        }
    }

    /// <summary>
    /// The 'Invoker' class
    /// 使用者
    /// </summary>
    class User
    {
        // Initializers
        private Calculator _calculator = new Calculator();
        private List<Command> _commands = new List<Command>();
        private int _current = 0;

        /// <summary>
        /// 用户重做
        /// </summary>
        /// <param name="levels"></param>
        public void Redo(int levels)
        {
            for (int i = 0; i < levels; i++)
            {
                if (_current < _commands.Count - 1)
                {
                    Command command = _commands[_current++];
                    command.Execute();
                }
            }
        }

        /// <summary>
        /// 用户撤销
        /// </summary>
        /// <param name="levels"></param>
        public void Undo(int levels)
        {
            Debug.Log("\n---- Undo "+ levels + " levels");
            // Perform undo operations
            for (int i = 0; i < levels; i++)
            {
                if (_current > 0)
                {
                    Command command = _commands[--_current] as Command;
                    command.UnExecute();
                }
            }
        }

        /// <summary>
        /// 计算
        /// </summary>
        /// <param name="operator"></param>
        /// <param name="operand"></param>
        public void Compute(char @operator, int operand)
        {
            // Create command operation and execute it
            Command command = new CalculatorCommand(
              _calculator, @operator, operand);
            command.Execute();

            // Add command to undo list
            _commands.Add(command);
            _current++;
        }
    }
}

命令模式案例2

using System.Collections.Generic;
using UnityEngine;

namespace CommandPatternExample4
{
	public class CommandPatternExample4 : MonoBehaviour
    {
        void Start()
        {
            Invoker theInvoker = new Invoker();

            Command theCommand = null;
            // 结合命令与执行者
            theCommand = new ConcreteCommand1(new Receiver1(), "hi");
            theInvoker.AddCommand(theCommand);
            theCommand = new ConcreteCommand2(new Receiver2(), 666);
            theInvoker.AddCommand(theCommand);

            // 进行执行
            theInvoker.ExecuteCommand();
        }

    }


    /// <summary>
    /// 命令抽象类
    /// </summary>
    public abstract class Command
    {
        public abstract void Execute();
    }

    /// <summary>
    /// 实际命令1-绑定命令和receiver
    /// </summary>
    public class ConcreteCommand1 : Command
    {
        Receiver1 m_Receiver = null;
        string m_Command = "";

        public ConcreteCommand1(Receiver1 Receiver, string param)
        {
            m_Receiver = Receiver;
            m_Command = param;
        }

        public override void Execute()
        {
            m_Receiver.Action(m_Command);
        }
    }

    /// <summary>
    /// 实际命令2-绑定命令和receiver
    /// </summary>
    public class ConcreteCommand2 : Command
    {
        Receiver2 m_Receiver = null;
        int m_Param = 0;

        public ConcreteCommand2(Receiver2 Receiver, int Param)
        {
            m_Receiver = Receiver;
            m_Param = Param;
        }

        public override void Execute()
        {
            m_Receiver.Action(m_Param);
        }
    }

    /// <summary>
    /// 功能执行者1
    /// </summary>
    public class Receiver1
    {
        public Receiver1() { }
        public void Action(string param)
        {
            Debug.Log("Receiver1.Action:Command[" + param + "]");
        }
    }

    /// <summary>
    /// 功能执行者2
    /// </summary>
    public class Receiver2
    {
        public Receiver2() { }
        public void Action(int Param)
        {
            Debug.Log("Receiver2.Action:Param[" + Param.ToString() + "]");
        }
    }


    /// <summary>
    /// 命令管理者
    /// </summary>
    public class Invoker
    {
        List<Command> m_Commands = new List<Command>();

        // 加入命令
        public void AddCommand(Command theCommand)
        {
            m_Commands.Add(theCommand);
        }

        /// <summary>
        /// 执行命令
        /// </summary>
        public void ExecuteCommand()
        {
            // 执行
            foreach (Command theCommand in m_Commands)
                theCommand.Execute();
            // 清空 
            m_Commands.Clear();
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值