Command
Материал из Википедии — свободной энциклопедии
Команда — шаблон проектирования, используемый при объектно-ориентированном программировании, представляющий действие. Объект команды заключает в себе само действие и его параметры.
Содержание |
[править] Описание
| Название | команда |
|---|---|
| Английское название | command |
| Диаграмма | ![]() |
| Тип | поведенческий |
| Назначение | для обработки команды в виде объекта
|
| Родственные шаблоны | Composite/Компоновщик, Memento, Прототип, Singleton |
Обеспечивает обработку команды в виде объекта, что позволяет сохранять её, передавать в качестве параметра методам, а также возвращать её в виде результата, как и любой другой объект.
Например, библиотека печати может иметь класс PrintJob. Для его использования можно создать объект PrintJob, установить необходимые параметры, и вызвать метод, непосредственно отсылающий задание на печать.
[править] Примеры
[править] Пример С#
using System; using System.Collections.Generic; namespace Command { class MainApp { static void Main() { // Создаем пользователя. User user = new User(); // Пусть он что-нибудь сделает. user.Compute('+', 100); user.Compute('-', 50); user.Compute('*', 10); user.Compute('/', 2); // Отменяем 4 команды user.Undo(4); // Вернём 3 отменённые команды. user.Redo(3); // Ждем ввода пользователя и завершаемся. Console.Read(); } } // "Command" : абстрактная Команда abstract class Command { public abstract void Execute(); public abstract void UnExecute(); } // "ConcreteCommand" : конкретная команда class CalculatorCommand : Command { char @operator; int operand; Calculator calculator; // Constructor public CalculatorCommand(Calculator calculator, char @operator, int operand) { this.calculator = calculator; this.@operator = @operator; this.operand = operand; } public char Operator { set{ @operator = value; } } public int Operand { set{ operand = value; } } public override void Execute() { calculator.Operation(@operator, operand); } public override void UnExecute() { calculator.Operation(Undo(@operator), operand); } // Private helper function : приватные вспомогательные функции private char Undo(char @operator) { char undo; switch(@operator) { case '+': undo = '-'; break; case '-': undo = '+'; break; case '*': undo = '/'; break; case '/': undo = '*'; break; default : undo = ' '; break; } return undo; } } // "Receiver" : получатель class Calculator { private int curr = 0; 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; } Console.WriteLine( "Current value = {0,3} (following {1} {2})", curr, @operator, operand); } } // "Invoker" : вызывающий class User { // Initializers private Calculator calculator = new Calculator(); private List<Command> commands = new List<Command>(); private int current = 0; public void Redo(int levels) { Console.WriteLine("\n---- Redo {0} levels ", levels); // Делаем возврат операций for (int i = 0; i < levels; i++) if (current < commands.Count - 1) commands[current++].Execute(); } public void Undo(int levels) { Console.WriteLine("\n---- Undo {0} levels ", levels); // Делаем отмену операций for (int i = 0; i < levels; i++) if (current > 0) commands[--current].UnExecute(); } public void Compute(char @operator, int operand) { // Создаем команду операции и выполняем её Command command = new CalculatorCommand( calculator, @operator, operand); command.Execute(); // Добавляем операцию к списку отмены commands.Add(command); current++; } } }
[править] Пример Java
/*the Invoker class*/ public class Switch { private Command flipUpCommand; private Command flipDownCommand; public Switch(Command flipUpCmd,Command flipDownCmd){ this.flipUpCommand=flipUpCmd; this.flipDownCommand=flipDownCmd; } public void flipUp(){ flipUpCommand.execute(); } public void flipDown(){ flipDownCommand.execute(); } } /*Receiver class*/ public class Light{ public Light(){ } public void turnOn(){ System.out.println("The light is on"); } public void turnOff(){ System.out.println("The light is off"); } } /*the Command interface*/ public interface Command{ void execute(); } /*the Command for turning on the light*/ public class TurnOnLightCommand implements Command{ private Light theLight; public TurnOnLightCommand(Light light){ this.theLight=light; } public void execute(){ theLight.turnOn(); } } /*the Command for turning off the light*/ public class TurnOffLightCommand implements Command{ private Light theLight; public TurnOffLightCommand(Light light){ this.theLight=light; } public void execute(){ theLight.turnOff(); } } /*The test class*/ public class TestCommand{ public static void main(String[] args){ Light l=new Light(); Command switchUp=new TurnOnLightCommand(l); Command switchDown=new TurnOffLightCommand(l); Switch s=new Switch(switchUp,switchDown); s.flipUp(); s.flipDown(); } }
[править] Пример JavaScript
// Command: абстрактная Команда function Command() { this.execute = function() {}; this.unExecute = function() {}; } // ConcreteCommand: конкретная команда function CalculatorCommand() { var calculator; var operator; var operand; this.execute = function(newCalculator, newOperator, newOperand) { // установка параметров команды if (typeof(newCalculator)=="object" && typeof(newOperator)=="string" && typeof(newOperand)=="number") { calculator = newCalculator; operator = newOperator; operand = newOperand; } // исполнение команды calculator.operation(operator, operand); }; this.unExecute = function() { // исполнение обратной команды calculator.operation(undo(operator), operand); }; function undo(operator) { // функция вернет оператор, обратный переданному // при желании, можно воспользоваться замыканием и не передавать оператор switch(operator) { case '+': return '-'; break; case '-': return '+'; break; } return ' '; // результат по умолчанию } } CalculatorCommand.prototype = new Command(); CalculatorCommand.prototype.constructor = CalculatorCommand; // Receiver: получатель function Calculator() { var val = 0; this.operation = function(operator, operand) { // производим операцию switch(operator) { case '+': val += operand; debug(operator, operand); break; case '-': val -= operand; debug(operator, operand); break; default: alert("Неизвестный оператор"); break; } }; function debug(operator, operand) { alert("Текущее значение: "+ val +"\nОперация: "+ operator + operand); } } // Invoker: вызывающий function User() { var calculator = new Calculator(); var commands = []; // массив команд current = 0; // номер текущей команды this.compute = function(operator, operand) { var newCommand = new CalculatorCommand(); if (current<commands.length-1) { // если "внутри undo" мы запускаем новую операцию, // надо обрубать список команд, следующих после текущей, // иначе undo/redo будут некорректны commands.splice(current); } newCommand.execute(calculator, operator, operand); commands.push(newCommand); current++; }; this.undo = function(levels) { alert("отмена ("+ levels +")"); for (i=0; i<levels; i++) { if (current > 0) { commands[--current].unExecute(); } } }; this.redo = function(levels) { alert("возврат ("+ levels +")"); for (i=0; i<levels; i++) { if (current < commands.length) { commands[current++].execute(); } } }; } // использование var u = new User(); u.compute("+", 2); // 2, "+2" u.compute("+", 3); // 5, "+3" u.compute("-", 1); // 4, "-1" u.compute("+", 6); // 10, "+6" u.undo(3); // 4, "-6" // 5, "+1" // 2, "-3" u.redo(2); // 5, "+3" // 4, "-1" u.undo(2); // 5, "+1" // 2, "-3" u.compute("+", 8); // 10, "+8" u.undo(1); // 2, "-8" u.redo(2); // 10, "+8" // превышение длинны commands u.compute("+", 9); // 19, "+9"
Для улучшения этой статьи желательно?:
|


