Команда (Command) — различия между версиями

Материал из Вики ИТ мехмата ЮФУ
Перейти к: навигация, поиск
(Описание)
(Достоинства и недостатки)
Строка 133: Строка 133:
  
 
=== Достоинства и недостатки ===
 
=== Достоинства и недостатки ===
*  
+
* Отделение вызова операции от алгоритма выполнения этой операции
 +
* Совместное использование команд разными объектами
 +
* Команда как объект обладает всеми преимуществами объектов: ее можно расширять, можно скрывать данные и проч.
 +
* Из простых команд можно собирать составные (макрокоманды - суперпозиция команд)
  
 
=== Варианты ===
 
=== Варианты ===
 
*
 
*

Версия 08:57, 2 августа 2014

К основной странице курса

Другое имя

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

Назначение

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

Описание

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

Реализация

Диаграмма классов

CommandCommon.png

Участники

  • Command - команда

Объявляет интерфейс для выполнения операции, состоящий из метода Execute и, возможно, UnExecute

  • ConcreteCommand - конкретная команда

Реализует метод Execute, вызывая методы Receiverа

  • Client - клиент

Создает объект класса ConcreteCommand и устанавливает его получателя (Receiverа). Получатель команды - это дурацкое непонятное название, смысл которого в следующем. Receiver называется получателем команды если команда вызывает его методы.

  • Invoker - инициатор

Обращается к команде для выполнения запроса (вызывает ее метод Execute)

  • Receiver - получатель

Умеет выполнять операции, необходимые для реализации команд. Как правило, передается в команду в качестве параметра конструктора.

Пример

Этот пример в WDE

using System;
using System.Collections.Generic;

class AruthmeticUnit // Receiver
{
  private double res = 0;
  public void Add(double x)
  {
    res += x;
  }
  public void Sub(double x)
  {
    res -= x;
  }
  public void Div(double x)
  {
    res /= x;
  }
  public void Mult(double x)
  {
    res *= x;
  }
  public double Result
  {
    get { return res; }
  }
}

abstract class Command
{
  public readonly AruthmeticUnit unit;
  public Command(AruthmeticUnit unit)
  {
    this.unit = unit;
  }
  public abstract void Execute();
}

class BinaryCommand: Command
{
  private char op;
  private double x;
  public BinaryCommand(AruthmeticUnit unit, char op, double x): base(unit)
  {
    this.op = op;
    this.x = x;
  }
  public override void Execute()
  {
    switch (op)
    {
      case '+': 
        unit.Add(x);
        break;
      case '-': 
        unit.Sub(x);
        break;
      case '*': 
        unit.Mult(x);
        break;
      case '/': 
        unit.Div(x);
        break;
    }
  }
}

class ChangeSignCommand: Command
{
  public ChangeSignCommand(AruthmeticUnit unit): base(unit)
  { }
  public override void Execute()
  {
    unit.Mult(-1);
  }
}

class My // Одновременно Client (создает команды и Receiverа) и Invoker (выполняет команды)
{
  public static void Main()
  {
    // Действия Clientа
    var unit = new AruthmeticUnit();
    var l = new List<Command>();
    l.Add(new BinaryCommand(unit,'+',2));
    l.Add(new BinaryCommand(unit,'*',3));
    l.Add(new BinaryCommand(unit,'-',1));
    l.Add(new BinaryCommand(unit,'*',2));
    l.Add(new ChangeSignCommand(unit));
    
    // Действия Invokerа
    foreach (var c in l)
      c.Execute();
    Console.WriteLine(unit.Result);  
  }
}

Нетрудно реализовать метод UnExecute, выподняющий противоположное действие. Для отката действий необходимо выполнить UnExecute для команд в обратном порядке.

Достоинства и недостатки

  • Отделение вызова операции от алгоритма выполнения этой операции
  • Совместное использование команд разными объектами
  • Команда как объект обладает всеми преимуществами объектов: ее можно расширять, можно скрывать данные и проч.
  • Из простых команд можно собирать составные (макрокоманды - суперпозиция команд)

Варианты