背景
- 通过命令解耦接收者和调用者。
- 接收者,处理具体请求。
- 命令,绑定接收者和请求。
- 调用者=命令容器,可执行和撤销命令。
示例
using System.Collections.Generic;
using static System.Console;
namespace DesignPattern_Command
{
// 接收者类,处理具体请求
public class Calculator
{
private int result = 0;
public Calculator() { }
// @允许使用系统保留字
// 请求= @operator & operand
public void Evaluate(char @operator, int operand)
{
var fx = $"{result} {@operator} {operand} ";
switch (@operator)
{
case '+':
result += operand;
break;
case '-':
result -= operand;
break;
case '*':
result *= operand;
break;
case '/':
result /= operand;
break;
}
WriteLine($"{result}= {fx}");
}
}
// 命令接口
public interface ICommand
{
void Do();
void Undo();
}
// 具体命令类,绑定接收者和请求
public class Command : ICommand
{
private readonly Calculator calculator;
private readonly char @operator;
private readonly int operand;
private readonly Dictionary<char, char> opposites = new Dictionary<char, char>
{
['+'] = '-',
['-'] = '+',
['*'] = '/',
['/'] = '*',
};
public Command(Calculator c, char @operator, int operand)
{
calculator = c;
this.@operator = @operator;
this.operand = operand;
}
public void Do()
=> calculator.Evaluate(@operator, operand);
public void Undo()
=> calculator.Evaluate(opposites[@operator], operand);
}
// 调用者=命令容器,执行或撤销命令
public class User
{
private int current = -1;
private List<ICommand> commands = new List<ICommand>();
private readonly Calculator calculator;
public User(Calculator c)
{
calculator = c;
}
public void Redo(int steps)
{
current++; // 从已实施的下一步开始
for (int step = 1; step <= steps; step++)
{
if (current == commands.Count) break;
commands[current++].Do();
}
}
public void Undo(int steps)
{
// 从已实施开始
for (int step = 1; step <= steps; step++)
{
if (current == -1) break;
commands[current--].Undo();
}
}
public void Compute(char @operator, int operand)
{
var command = new Command(calculator, @operator, operand);
commands.Add(command);
command.Do();
current++;
}
}
public class Client
{
public Client() { }
public void Execute()
{
var calculator = new Calculator();
var user = new User(calculator);
user.Compute('+', 100);
user.Compute('-', 50);
user.Compute('*', 2);
user.Compute('/', 100);
WriteLine();
user.Undo(2);
WriteLine();
user.Redo(4);
}
}
class Program
{
static void Main(string[] args)
{
var client = new Client();
client.Execute();
ReadKey();
}
}
}
网友评论