Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Design Patterns via C#.pdf
Скачиваний:
154
Добавлен:
17.03.2016
Размер:
13.25 Mб
Скачать

175

Паттерн Command

Название

Команда

Также известен как

Action (Действие), Transaction (Транзакция)

Классификация

По цели: поведенческий По применимости: к объектам

Частота использования

Выше средней - 1 2 3 4 5

Назначение

Паттерн Command – позволяет представить запрос в виде объекта, позволяя клиенту конфигурировать запрос (задавая параметры для его обработки), ставить запросы в очередь, протоколировать запросы, а также поддерживать отмену операций.

Введение

В качестве примера системы, в которой возможно использовать паттерн Command предлагается рассмотреть упрощенный программный калькулятор с четырьмя арифметическими операциями Add, Sub, Mul, Div и двумя операциями Undo и Redo. Структурная схема калькулятора показана на рисунке ниже.

Вструктуре калькулятора можно выделить UI (наборное поле с кнопками для цифр, знаков отмены

иповтора операций, а также панель для отображения результата). В «корпусе» калькулятора расположены программные блоки, обеспечивающие реакцию калькулятора на поток внешних дискретных событий. Такими событиями являются нажатия кнопок наборного поля.

Состав программных блоков калькулятора, следующий:

176

УУ - Устройство управления (ControlUnit). Оно организует всю работу калькулятора, выдавая в подходящий момент элементарные объекты-команды типа: Add, Sub, Mul, Div, Undo, Redo. При этом УУ сохраняет историю использования команд, а также может отменять и восстанавливать ранее выполненные команды.

АУ - Арифметическое устройство (ArithmeticUnit). После получения «сигнала» (одной из четырех команд Add, Sub, Mul, Div) на вход выполняет арифметическую операцию.

Команды - Add, Sub, Mul, Div. Специальные объекты-команды, которые УУ использует для управления АУ. Каждый объект-команда связан с АУ и умеет правильно им управлять.

Предлагается рассмотреть диаграмму классов на которой представлена модель калькулятора.

См. Пример к главе: \014_Command\002_Command_Undo_Redo

177

Ниже представлен пример реализации калькулятора.

// "Command"

abstract class Command

{

protected ArithmeticUnit unit; protected int operand;

public abstract void Execute(); public abstract void UnExecute();

}

Add

// "ConcreteCommand" class Add : Command

{

public Add(ArithmeticUnit unit, int operand)

{

this.unit = unit; this.operand = operand;

}

public override void Execute()

{

unit.Run('+', operand);

}

public override void UnExecute()

{

unit.Run('-', operand);

}

}

Sub

// "ConcreteCommand" class Sub : Command

{

public Sub(ArithmeticUnit unit, int operand)

{

this.unit = unit; this.operand = operand;

}

public override void Execute()

{

unit.Run('-', operand);

}

public override void UnExecute()

{

unit.Run('+', operand);

}

}

Div

// "ConcreteCommand" class Div : Command

{

public Div(ArithmeticUnit unit, int operand)

{

this.unit = unit; this.operand = operand;

}

public override void Execute()

{

unit.Run('/', operand);

}

public override void UnExecute()

{

unit.Run('*', operand);

}

}

Mul

// "ConcreteCommand" class Mul : Command

{

public Mul(ArithmeticUnit unit, int operand)

{

this.unit = unit; this.operand = operand;

}

public override void Execute()

{

unit.Run('*', operand);

}

public override void UnExecute()

{

unit.Run('/', operand);

}

}

См. продолжение примера на следующей странице.

class Program

 

 

 

 

 

 

 

{

 

 

 

 

 

 

 

static void Main()

 

 

 

 

 

{

 

 

 

 

 

 

 

var calculator = new Calculator();

 

 

int result = 0;

 

 

 

 

 

result =

calculator.Add(5);

 

 

 

 

 

Console.WriteLine(result);

 

 

 

 

 

result =

calculator.Sub(3);

 

 

 

 

 

Console.WriteLine(result);

 

 

 

 

 

result = calculator.Undo(2);

 

 

 

 

 

Console.WriteLine(result);

 

 

 

 

 

result =

calculator.Redo(1);

 

 

 

 

 

Console.WriteLine(result);

 

 

 

 

 

}

 

 

 

 

 

 

 

}

 

 

 

 

 

 

 

 

 

 

Калькулятор

 

 

 

// "Client"

 

 

Команды для АУ

 

 

 

class Calculator

 

 

Add

 

Sub

Div

Mu l

{

 

 

 

 

 

 

 

ArithmeticUnit arithmeticUnit;

 

 

 

 

 

ControlUnit controlUnit;

 

УУ

 

 

АУ

 

 

 

устройство

 

 

 

Устро йство управления

 

Ари фметическое

 

 

 

 

 

public Calculator()

 

 

 

 

 

{

 

 

 

 

 

 

 

arithmeticUnit

= new ArithmeticUnit();

 

controlUnit =

new ControlUnit();

 

 

 

 

}

 

 

 

 

 

 

 

private int Run(Command command)

 

 

 

 

 

{

 

 

 

 

 

 

 

controlUnit.StoreCommand(command);

 

 

 

controlUnit.ExecuteCommand();

 

 

 

 

 

return arithmeticUnit.Register;

 

 

 

 

}

 

 

 

 

 

 

 

public int Add(int operand)

 

 

 

 

 

{

 

 

 

 

 

 

 

return Run(new Add(arithmeticUnit, operand));

}

 

 

 

 

 

 

 

public int Sub(int operand)

 

 

 

 

 

{

 

 

 

 

 

 

 

return Run(new Sub(arithmeticUnit, operand));

}

 

 

 

 

 

 

 

public int Mul(int operand)

 

 

 

 

 

{

 

 

 

 

 

 

 

return Run(new Mul(arithmeticUnit, operand));

}

 

 

 

 

 

 

 

public int Div(int operand)

 

 

 

 

 

{

 

 

 

 

 

 

 

return Run(new Div(arithmeticUnit, operand));

}

 

 

 

 

 

 

 

public int Undo(int levels)

 

 

 

 

 

{

 

 

 

 

 

 

 

controlUnit.Undo(levels);

 

 

 

 

 

return arithmeticUnit.Register;

 

 

 

 

}

 

 

 

 

 

 

 

public int Redo(int levels)

 

 

 

 

 

{

 

 

 

 

 

 

 

controlUnit.Redo(levels);

 

 

 

 

 

return arithmeticUnit.Register;

 

 

 

 

}

 

 

 

 

 

 

 

}

 

 

 

 

 

 

 

178

 

УУ

// "Invoker" (Инициатор)

Устройство

управления

// Устройство управления (УУ)

 

class ControlUnit

 

{

 

private List<Command> commands =

 

new List<Command>();

private int current = 0;

 

public void StoreCommand(Command command)

{

 

commands.Add(command);

 

}

 

public void ExecuteCommand()

 

{

 

commands[current].Execute();

 

current++;

 

}

 

public void Undo(int levels)

 

{

 

for (int i = 0; i < levels; i++)

 

if (current > 0)

 

commands[--current].UnExecute();

}

 

public void Redo(int levels)

 

{

 

for (int i = 0; i < levels; i++)

 

if (current < commands.Count -

1)

commands[current++].Execute();

}

 

}

 

 

 

 

АУ

 

 

Арифметическое

// "Receiver" (Получатель)

 

устройство

// Арифметическое устройство (АУ)

 

 

class ArithmeticUnit

 

 

 

{

 

 

 

public int Register { get;

private set;

}

public void Run(char operationCode, int operand)

{

 

 

 

switch (operationCode)

 

 

 

{

 

 

 

case '+':

 

 

 

Register += operand;

 

 

break;

 

 

 

case '-':

 

 

 

Register -= operand;

 

 

break;

 

 

 

case '*':

 

 

 

Register *= operand;

 

 

break;

 

 

 

case '/':

 

 

 

Register /= operand;

 

 

break;

 

 

 

}

 

 

 

}

 

 

 

}

 

 

 

См. Пример к главе: \014_Command\002_Command_Undo_Redo

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]