命令模式(Command)

来源:互联网 发布:齐鲁大学生软件大赛 编辑:程序博客网 时间:2024/05/20 03:44

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>

  classMainApp

  {

    ///<summary>

    /// Entry point into console application.

    ///</summary>

    staticvoid 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>

  abstractclass Command

  {

    protectedReceiver receiver;

 

    // Constructor

    public Command(Receiver receiver)

    {

      this.receiver = receiver;

    }

 

    publicabstract void Execute();

  }

 

  ///<summary>

  /// The 'ConcreteCommand' class

  ///</summary>

  classConcreteCommand : Command

  {

    // Constructor

    public ConcreteCommand(Receiver receiver) :

      base(receiver)

    {

    }

 

    publicoverride void Execute()

    {

      receiver.Action();

    }

  }

 

  ///<summary>

  /// The 'Receiver' class

  ///</summary>

  classReceiver

  {

    publicvoid Action()

    {

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

    }

  }

 

  ///<summary>

  /// The 'Invoker' class

  ///</summary>

  classInvoker

  {

    privateCommand _command;

 

    publicvoid SetCommand(Command command)

    {

      this._command = command;

    }

 

    publicvoid 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>

  classMainApp

  {

    ///<summary>

    /// Entry point into console application.

    ///</summary>

    staticvoid 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>

  abstractclass Command

  {

    publicabstract void Execute();

    publicabstract void UnExecute();

  }

 

  ///<summary>

  /// The 'ConcreteCommand' class

  ///</summary>

  classCalculatorCommand : Command

  {

    privatechar _operator;

    privateint _operand;

    privateCalculator _calculator;

 

    // Constructor

    public CalculatorCommand(Calculator calculator,

      char @operator,int operand)

    {

      this._calculator = calculator;

      this._operator = @operator;

      this._operand = operand;

    }

 

    // Gets operator

    publicchar Operator

    {

      set { _operator =value; }

    }

 

    // Get operand

    publicint Operand

    {

      set { _operand =value; }

    }

 

    // Execute new command

    publicoverride void Execute()

    {

      _calculator.Operation(_operator, _operand);

    }

 

    // Unexecute last command

    publicoverride void UnExecute()

    {

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

    }

 

    // Returns opposite operator for given operator

    privatechar Undo(char @operator)

    {

      switch (@operator)

      {

        case'+': return '-';

        case'-': return '+';

        case'*': return '/';

        case'/': return '*';

        default:throw new

         ArgumentException("@operator");

      }

    }

  }

 

  ///<summary>

  /// The 'Receiver' class

  ///</summary>

  classCalculator

  {

    privateint _curr = 0;

 

    publicvoid 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>

  classUser

  {

    // Initializers

    privateCalculator _calculator = new Calculator();

    privateList<Command> _commands =new List<Command>();

    privateint _current = 0;

 

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

        }

      }

    }

 

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

        }

      }

    }

 

    publicvoid 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

原创粉丝点击