using System;
using System.Collections.Generic;
// Command interface
public interface ICommand
{
void Execute();
void Undo();
}
// Concrete command
public class AddCommand : ICommand
{
private Calculator _calculator;
private int _value;
public AddCommand(Calculator calculator, int value)
{
_calculator = calculator;
_value = value;
}
public void Execute()
{
_calculator.Add(_value);
}
public void Undo()
{
_calculator.Subtract(_value);
}
}
// Receiver
public class Calculator
{
private int _currentValue;
public void Add(int value)
{
_currentValue += value;
Console.WriteLine($"Added {value}. Current value = {_currentValue}");
}
public void Subtract(int value)
{
_currentValue -= value;
Console.WriteLine($"Subtracted {value}. Current value = {_currentValue}");
}
}
// Invoker
public class Invoker
{
private Stack _commands = new Stack();
public void ExecuteCommand(ICommand command)
{
command.Execute();
_commands.Push(command);
}
public void UndoLastCommand()
{
if (_commands.Count > 0)
{
ICommand lastCommand = _commands.Pop();
lastCommand.Undo();
}
else
{
Console.WriteLine("No more commands to undo");
}
}
}
class Program
{
static void Main(string[] args)
{
// Client code
Calculator calculator = new Calculator();
Invoker invoker = new Invoker();
ICommand addCommand = new AddCommand(calculator, 10);
invoker.ExecuteCommand(addCommand);
ICommand subtractCommand = new AddCommand(calculator, 5);
invoker.ExecuteCommand(subtractCommand);
invoker.UndoLastCommand(); // Undo subtractCommand
invoker.UndoLastCommand(); // Undo addCommand
}
}
In essence, the Command Pattern promotes loose coupling between objects by turning requests into objects. This flexibility and separation of concerns make it a powerful tool in designing systems where operations need to be encapsulated, queued, logged, and possibly undone.