命令模式介绍
命令模式将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象,同时支持可撤消的操作。
命令模式
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();
}
}
}