/* Команда
Инкапсулирует запрос в виде объекта
позволяя передавать их клиентам в
качестве параметров, ставить в очередь,
логировать, а также поддерживать отмену
операций
*/
class Program
{
static void Main()
{
#region Пример №1 - базовое
var initCommand = new Invoker(new ConcreteCommand(new Receiver()));
initCommand.Run();
initCommand.Cancel();
Console.WriteLine("Please press Enter...");
Console.ReadKey();
#endregion
#region Пример №2 - пульт управления конвеерной установкой
var conveyor = new Conveyor(); // создаём конвеер
var multipult = new Multipult(); // создаём пульт управления конвеером
multipult.SetCommand(0, new ConveyorWorkCommand(conveyor));
multipult.SetCommand(1, new ConveyorAjustCommand(conveyor));
multipult.PressOn(0);
multipult.PressOn(1);
multipult.PressCansel();
multipult.PressCansel();
#endregion
}
}
///
/// Описания общего поведения объекта
///
abstract class Command
{
public abstract void Execute();
public abstract void Undo();
}
///
/// Описание процесса создания команды
///
class ConcreteCommand : Command
{
Receiver receiver;
public ConcreteCommand(Receiver receiver)
{
this.receiver = receiver;
}
///
/// Инициализация команды
/// *вызывает его получателя
///
public override void Execute()
{
receiver.Operation();
}
///
/// Остановка команды
///
public override void Undo()
{
Console.WriteLine("Stop");
}
}
///
/// Описание возможностей получателя команды
///
class Receiver
{
///
/// Обработка получателем команды
///
public void Operation()
{
Console.WriteLine("Processing...");
}
}
///
/// Описание инициатора команды
///
class Invoker
{
Command command;
///
/// Принимает в себя команду
///
/// #
public Invoker(Command command)
{
this.command = command;
}
///
/// Запускает команду
///
public void Run()
{
command.Execute();
}
///
/// Отменяет выполнение команды
///
public void Cancel()
{
command.Undo();
}
}
///
/// Поведение команды
///
interface ICommand
{
void Positive();
void Negative();
}
///
/// Класс конвеера
///
class Conveyor
{
public void On() => Console.WriteLine("Включение конвеера");
public void Off() => Console.WriteLine("Выключение конвеера");
public void SpeedIncrease() => Console.WriteLine("Скорость конвеера увеличена");
public void SpeedDecrease() => Console.WriteLine("Скорость конвеера снижена");
}
///
/// Класс управления работой конвеера
///
class ConveyorWorkCommand : ICommand
{
public Conveyor conveer;
///
/// Передача типа конвеера в конструторе
///
/// тип
public ConveyorWorkCommand(Conveyor conveer) => this.conveer = conveer;
public void Negative() => conveer.Off();
public void Positive() => conveer.On();
}
///
/// Класс регулировки конвеера
///
class ConveyorAjustCommand : ICommand
{
public Conveyor conveer;
///
/// Передача типа конвеера в конструторе
///
/// тип
public ConveyorAjustCommand(Conveyor conveer) => this.conveer = conveer;
public void Negative() => conveer.SpeedDecrease();
public void Positive() => conveer.SpeedIncrease();
}
///
/// Пульт управления конвеером
///
class Multipult
{
///
/// Все возможные команды
///
private List commands;
///
/// История выполненных команд для возможной их отмены
///
private Stack history;
public Multipult()
{
commands = new List() { null, null };
history = new Stack();
}
///
/// Устанавлием список команд по индексу кнопки
///
public void SetCommand(int btn, ICommand command) => commands[btn] = command;
///
/// Вызывает команду из списка по указанному индексу
/// и запишет в историю команд выполненную команду
///
/// идекс кнопки
public void PressOn(int btn)
{
commands[btn].Positive();
history.Push(commands[btn]);
}
///
/// Извлекает команду из истории и отменяет её
///
public void PressCansel()
{
if(history.Count == 0) return;
var oldC = history.Pop();
oldC.Negative();
}
}