• Net设计模式实例之命令模式(Command Pattern)


    一、命令模式简介(Brief Introduction

    命令模式(Command Pattern)将请求封装为一个对象,从而使你用不同的请求对客户进行参数化,对请求排队或纪录请求日志,以及支持可撤销的操作。

    Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations

    二、解决的问题(What To Solve

           当需要有撤销或者恢复操作时,可以考虑使用命令模式。

    三、命令模式分析(Analysis

    1、命令模式结构

    Command抽象类:声明一个接口,用于执行操作,declares an interface for executing an operation

    ConcreteCommand实现类:将一个接收者对象绑定到一个动作。调用接收者相应的操作,以实现Execute

    defines a binding between a Receiver object and an action

    implements Execute by invoking the corresponding operation(s) on Receiver

    Receiver:知道如何执行一个请求相关的操作。knows how to perform the operations associated with carrying out the request.

    Invoker:要求命令执行一个请求。asks the command to carry out the request

    2、源代码

    1Command抽象类声明一个接口,用于执行操作

    abstract class Command

    {

        protected Receiver receiver;

     

        public Command(Receiver receiver)

        {

            this.receiver = receiver;

        }

        public abstract void Execute();

    }

     

    2ConcreteCommand具体实现类:将一个接收者对象绑定到一个动作

    class ConcreteCommand : Command

    {

        // Constructor

        public ConcreteCommand(Receiver receiver)

            :base(receiver)

        {

        }

        public override void Execute()

        {

            receiver.Action();

        }

    }

     

    3Receiver类:知道如何执行一个请求相关的操作

    class Receiver

    {

        public void Action()

        {

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

        }

    }

     

    4Invoker类:要求命令执行一个请求

    class Invoker

    {

        private Command _command;

        public void SetCommand(Command command)

        {

            this._command = command;

        }

        public void ExecuteCommand()

        {

            _command.Execute();

        }

    }

     

    4、客户端代码

    static void Main(string[] args)

    {

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

     

        Console.ReadKey();

    }

    3、程序运行结果

    四.案例分析(Example

    1、场景

    使用命令模式进行计算器计算,可以是加减乘除等运算,可以进行Undo操作和Rodo操作。如下图所示

     

    Command抽象命令类:声明一个接口,用于执行操作。

    CalculatorCommand具体实现类:将一个接收者对象绑定到一个动作。调用接收者相应的操作,以实现Execute

    UnExecute方法:执行Undo操作。

    Calculator -Operation方法:执行加减乘除操作。

    User:要求命令Calculator执行一个计算请求。

    Compute方法:加减乘除等计算操作

    Undo方法:撤销操作。Redo方法:重复操作。

    2、代码

    1、抽象命令类Command及其计算器类CalculatorCommand

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

            }

        }

    }

     

    2、计算器类Calculator

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

        }

    }

     

    3、请求类User

    /// <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++;

        }

     

    4、客户端代码

    static void Main(string[] args)

    {

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

        Console.ReadKey();

    }

     

    3、程序运行结果

    五、总结(Summary

    命令模式(Command Pattern)将请求封装为一个对象,从而使你用不同的请求对客户进行参数化,对请求排队或纪录请求日志,以及支持可撤销的操作。当需要有撤销或者恢复操作时,可以考虑使用命令模式。

    作者:酷客多小程序

    出处: http://www.cnblogs.com/ywqu

    如果你认为此文章有用,请点击底端的【推荐】让其他人也了解此文章,

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    448-查找数组中消失的所有数字
    977 -排序数组的正方形
    爬虫小总结
    增量式爬虫
    分布式爬虫
    CrawlSpider:类,Spider的一个子类
    中间件
    中间件
    scrapy图片数据爬取之ImagesPipeline
    scrapy五大核心组件
  • 原文地址:https://www.cnblogs.com/ywqu/p/1658988.html
Copyright © 2020-2023  润新知