命令模式(Command)

1.    定义

       将一个请求封装为一个对象,从而使你可用不同的请求对客户数据进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。

2.      UML 类图

 

3.      结构代码

// Command pattern -- Structural example

using System;

 

namespace DoFactory.GangOfFour.Command.Structural

{

  /// <summary>

  /// MainApp startup class for Structural

  /// Command Design Pattern.

  /// </summary>

  class MainApp

  {

    /// <summary>

    /// Entry point into console application.

    /// </summary>

    static void Main()

    {

      // Create receiver, command, and invoker

      Receiver receiver = new Receiver();

      Command command = new ConcreteCommand(receiver);

      Invoker invoker = new Invoker();

 

      // Set and execute command

      invoker.SetCommand(command);

      invoker.ExecuteCommand();

 

      // Wait for user

      Console.ReadKey();

    }

  }

 

  /// <summary>

  /// The 'Command' abstract class

  /// </summary>

  abstract class Command

  {

    protected Receiver receiver;

 

    // Constructor

    public Command(Receiver receiver)

    {

      this.receiver = receiver;

    }

 

    public abstract void Execute();

  }

 

  /// <summary>

  /// The 'ConcreteCommand' class

  /// </summary>

  class ConcreteCommand : Command

  {

    // Constructor

    public ConcreteCommand(Receiver receiver) :

      base(receiver)

    {

    }

 

    public override void Execute()

    {

      receiver.Action();

    }

  }

 

  /// <summary>

  /// The 'Receiver' class

  /// </summary>

  class Receiver

  {

    public void Action()

    {

      Console.WriteLine("Called Receiver.Action()");

    }

  }

 

  /// <summary>

  /// The 'Invoker' class

  /// </summary>

  class Invoker

  {

    private Command _command;

 

    public void SetCommand(Command command)

    {

      this._command = command;

    }

 

    public void ExecuteCommand()

    {

      _command.Execute();

    }

  }

}


Output
Called Receiver.Action()

4.      实例代码

// Command pattern -- Real World example

using System;

using System.Collections.Generic;

 

namespace DoFactory.GangOfFour.Command.RealWorld

{

  /// <summary>

  /// MainApp startup class for Real-World

  /// Command Design Pattern.

  /// </summary>

  class MainApp

  {

    /// <summary>

    /// Entry point into console application.

    /// </summary>

    static void Main()

    {

      // Create user and let her compute

      User user = new User();

 

      // User presses calculator buttons

      user.Compute('+', 100);

      user.Compute('-', 50);

      user.Compute('*', 10);

      user.Compute('/', 2);

 

      // Undo 4 commands

      user.Undo(4);

 

      // Redo 3 commands

      user.Redo(3);

 

      // Wait for user

      Console.ReadKey();

    }

  }

 

  /// <summary>

  /// The 'Command' abstract class

  /// </summary>

  abstract class Command

  {

    public abstract void Execute();

    public abstract void UnExecute();

  }

 

  /// <summary>

  /// The 'ConcreteCommand' class

  /// </summary>

  class CalculatorCommand : Command

  {

    private char _operator;

    private int _operand;

    private Calculator _calculator;

 

    // Constructor

    public CalculatorCommand(Calculator calculator,

      char @operator, int operand)

    {

      this._calculator = calculator;

      this._operator = @operator;

      this._operand = operand;

    }

 

    // Gets operator

    public char Operator

    {

      set { _operator = value; }

    }

 

    // Get operand

    public int Operand

    {

      set { _operand = value; }

    }

 

    // Execute new command

    public override void Execute()

    {

      _calculator.Operation(_operator, _operand);

    }

 

    // Unexecute last command

    public override void UnExecute()

    {

      _calculator.Operation(Undo(_operator), _operand);

    }

 

    // Returns opposite operator for given operator

    private char Undo(char @operator)

    {

      switch (@operator)

      {

        case '+': return '-';

        case '-': return '+';

        case '*': return '/';

        case '/': return '*';

        default: throw new

         ArgumentException("@operator");

      }

    }

  }

 

  /// <summary>

  /// The 'Receiver' class

  /// </summary>

  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);

    }

  }

 

  /// <summary>

  /// The 'Invoker' class

  /// </summary>

  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);

      // Perform redo operations

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

      {

        if (_current < _commands.Count - 1)

        {

          Command command = _commands[_current++];

          command.Execute();

        }

      }

    }

 

    public void Undo(int levels)

    {

      Console.WriteLine("\n---- Undo {0} levels ", levels);

      // Perform undo operations

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

      {

        if (_current > 0)

        {

          Command command = _commands[--_current] as Command;

          command.UnExecute();

        }

      }

    }

 

    public void Compute(char @operator, int operand)

    {

      // Create command operation and execute it

      Command command = new CalculatorCommand(

        _calculator, @operator, operand);

      command.Execute();

 

      // Add command to undo list

      _commands.Add(command);

      _current++;

    }

  }

}


Output
Current value = 100 (following + 100)
Current value =  50 (following - 50)
Current value = 500 (following * 10)
Current value = 250 (following / 2)

---- Undo 4 levels
Current value = 500 (following * 2)
Current value =  50 (following / 10)
Current value = 100 (following + 50)
Current value =   0 (following - 100)

---- Redo 3 levels
Current value = 100 (following + 100)
Current value =  50 (following - 50)
Current value = 500 (following * 10)

该文章来自:http://www.dofactory.com/Patterns/PatternCommand.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值