Command
Название | команда |
---|---|
Английское название | command |
Диаграмма | Файл:Command.gif |
Тип | поведенческий |
Назначение | для обработки команды в виде объекта
|
Родственные шаблоны | 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"
Ошибка: неверное или отсутствующее изображение |
Для улучшения этой статьи желательно?:
|
bg:Команда (шаблон) de:Kommando (Entwurfsmuster) en:Command pattern es:Command (patrón de diseño) fr:Commande (patron de conception) he:תבנית Command it:Command pattern ja:Command パターン ko:커맨드 패턴 pl:Polecenie (wzorzec projektowy) uk:Команда (шаблон проектування) zh:命令模式
Если вам нравится SbUP.com Сайт, вы можете поддержать его - BTC: bc1qppjcl3c2cyjazy6lepmrv3fh6ke9mxs7zpfky0 , TRC20 и ещё....