命令模式(Command)

面向对象程式设计的范畴中,命令模式是一种设计模式,它尝试以物件来代表实际行动。命令物件可以把行动(action) 及其参数封装起来,于是这些行动可以被:

  • 重复多次
  • 取消(如果该物件有实作的话)
  • 取消后又再重做

这些都是现代大型应用程式所必须的功能,即“复原”及“重复”。除此之外,可以用命令模式来实作的功能例子还有:

  • 交易行为
  • 进度列
  • 精灵
  • 使用者接口按钮及功能表项目
  • 执行绪 pool
  • 宏收录


  • 定义:将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。



    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(
                  "当前值 = {0,3} (以下 {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---- 重做 {0} 水平 ", 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---- 撤销 {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)
            {
                // 创建命令操作,并执行它
                Command command = new CalculatorCommand(
                  _calculator, @operator, operand);
                command.Execute();
    
                //添加命令撤消列表
                _commands.Add(command);
                _current++;
            }
        }
    }

     

posted @ 2014-07-12 20:59  欢呼雀跃  阅读(212)  评论(0)    收藏  举报