Design Pattern - Command (C#)

小灰灰 2022-05-16 15:04 42阅读 0赞

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

Definition

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

Participants

The classes and/or objects participating in this pattern are:

  • Command (Command)

    • Declares an interface for executing an operation
  • ConcreteCommand (CalculatorCommand)

    • Defines a binding between a Receiver object and an action
    • Implements Execute by invoking the corresponding operation(s) on Receiver
  • Client (CommandApp)

    • Creates a ConcreteCommand object and sets its receiver
  • Invoker (User)

    • Asks the command to carry out the request
  • Receiver (Calculator)

    • Knows how to perform the operations associated with carrying out the request.

Sample Code in C#


This structural code demonstrates the Command pattern which stores requests as objects allowing clients to execute or playback the requests.

  1. // --------------------------------------------------------------------------------------------------------------------// <copyright company="Chimomo's Company" file="Program.cs">// Respect the work.// </copyright>// <summary>// Structural Command Design Pattern.// </summary>// --------------------------------------------------------------------------------------------------------------------namespace CSharpLearning{ using System; /// <summary> /// Startup class for Structural Command Design Pattern. /// </summary> internal static class Program { #region Methods /// <summary> /// Entry point into console application. /// </summary> private static void Main() { // Create receiver, command, and invoker var receiver = new Receiver(); Command command = new ConcreteCommand(receiver); var invoker = new Invoker(); // Set and execute command invoker.SetCommand(command); invoker.ExecuteCommand(); } #endregion } /// <summary> /// The 'Command' abstract class /// </summary> internal abstract class Command { #region Fields /// <summary> /// The receiver. /// </summary> protected readonly Receiver Receiver; #endregion // Constructor #region Constructors and Destructors /// <summary> /// Initializes a new instance of the <see cref="Command"/> class. /// </summary> /// <param name="receiver"> /// The receiver. /// </param> protected Command(Receiver receiver) { this.Receiver = receiver; } #endregion #region Public Methods and Operators /// <summary> /// The execute. /// </summary> public abstract void Execute(); #endregion } /// <summary> /// The 'ConcreteCommand' class /// </summary> internal class ConcreteCommand : Command { // Constructor #region Constructors and Destructors /// <summary> /// Initializes a new instance of the <see cref="ConcreteCommand"/> class. /// </summary> /// <param name="receiver"> /// The receiver. /// </param> public ConcreteCommand(Receiver receiver) : base(receiver) { } #endregion #region Public Methods and Operators /// <summary> /// The execute. /// </summary> public override void Execute() { this.Receiver.Action(); } #endregion } /// <summary> /// The 'Receiver' class /// </summary> internal class Receiver { #region Public Methods and Operators /// <summary> /// The action. /// </summary> public void Action() { Console.WriteLine("Called Receiver.Action()"); } #endregion } /// <summary> /// The 'Invoker' class /// </summary> internal class Invoker { #region Fields /// <summary> /// The command. /// </summary> private Command command; #endregion #region Public Methods and Operators /// <summary> /// The execute command. /// </summary> public void ExecuteCommand() { this.command.Execute(); } /// <summary> /// The set command. /// </summary> /// <param name="command"> /// The command. /// </param> public void SetCommand(Command command) { this.command = command; } #endregion }}// Output:/*Called Receiver.Action()*/

This real-world code demonstrates the Command pattern used in a simple calculator with unlimited number of undo’s and redo’s. Note that in C# the word ‘operator’ is a keyword. Prefixing it with ‘@’ allows using it as an identifier.

  1. // --------------------------------------------------------------------------------------------------------------------// <copyright company="Chimomo's Company" file="Program.cs">// Respect the work.// </copyright>// <summary>// Real-World Command Design Pattern.// </summary>// --------------------------------------------------------------------------------------------------------------------namespace CSharpLearning{ using System; using System.Collections.Generic; /// <summary> /// Startup class for Real-World Command Design Pattern. /// </summary> internal static class Program { #region Methods /// <summary> /// Entry point into console application. /// </summary> private static void Main() { // Create user and let her compute var 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); } #endregion } /// <summary> /// The 'Command' abstract class /// </summary> internal abstract class Command { #region Public Methods and Operators /// <summary> /// The execute. /// </summary> public abstract void Execute(); /// <summary> /// The un execute. /// </summary> public abstract void UnExecute(); #endregion } /// <summary> /// The 'ConcreteCommand' class /// </summary> internal class CalculatorCommand : Command { #region Fields /// <summary> /// The calculator. /// </summary> private readonly Calculator _calculator; /// <summary> /// The operand. /// </summary> private readonly int _operand; /// <summary> /// The operator. /// </summary> private readonly char _operator; #endregion // Constructor #region Constructors and Destructors /// <summary> /// Initializes a new instance of the <see cref="CalculatorCommand"/> class. /// </summary> /// <param name="calculator"> /// The calculator. /// </param> /// <param name="operator"> /// The @operator. /// </param> /// <param name="operand"> /// The operand. /// </param> public CalculatorCommand(Calculator calculator, char @operator, int operand) { this._calculator = calculator; this._operator = @operator; this._operand = operand; } #endregion // Execute new command #region Public Methods and Operators /// <summary> /// The execute. /// </summary> public override void Execute() { this._calculator.Operation(this._operator, this._operand); } /// <summary> /// Unexecute the last command. /// </summary> public override void UnExecute() { this._calculator.Operation(this.Undo(this._operator), this._operand); } #endregion // Returns opposite operator for given operator #region Methods /// <summary> /// The undo. /// </summary> /// <param name="operator"> /// The operator. /// </param> /// <returns> /// The <see cref="char"/>. /// </returns> private char Undo(char @operator) { switch (@operator) { case '+': return '-'; case '-': return '+'; case '*': return '/'; case '/': return '*'; default: throw new ArgumentException("@operator"); } } #endregion } /// <summary> /// The 'Receiver' class /// </summary> internal class Calculator { #region Fields /// <summary> /// The current value. /// </summary> private int curr; #endregion #region Public Methods and Operators /// <summary> /// The operation. /// </summary> /// <param name="operator"> /// The operator. /// </param> /// <param name="operand"> /// The operand. /// </param> public void Operation(char @operator, int operand) { switch (@operator) { case '+': this.curr += operand; break; case '-': this.curr -= operand; break; case '*': this.curr *= operand; break; case '/': this.curr /= operand; break; } Console.WriteLine("Current value = {0,3} (following {1} {2})", this.curr, @operator, operand); } #endregion } /// <summary> /// The 'Invoker' class /// </summary> internal class User { // Initializers #region Fields /// <summary> /// The calculator. /// </summary> private readonly Calculator calculator = new Calculator(); /// <summary> /// The commands. /// </summary> private readonly List<Command> commands = new List<Command>(); /// <summary> /// The current command. /// </summary> private int current; #endregion #region Public Methods and Operators /// <summary> /// The compute. /// </summary> /// <param name="operator"> /// The @operator. /// </param> /// <param name="operand"> /// The operand. /// </param> public void Compute(char @operator, int operand) { // Create command operation and execute it Command command = new CalculatorCommand(this.calculator, @operator, operand); command.Execute(); // Add command to undo list this.commands.Add(command); this.current++; } /// <summary> /// The redo. /// </summary> /// <param name="levels"> /// The levels. /// </param> public void Redo(int levels) { Console.WriteLine("\n---- Redo {0} levels ", levels); // Perform redo operations for (int i = 0; i < levels; i++) { if (this.current < this.commands.Count - 1) { Command command = this.commands[this.current++]; command.Execute(); } } } /// <summary> /// The undo. /// </summary> /// <param name="levels"> /// The levels. /// </param> public void Undo(int levels) { Console.WriteLine("\n---- Undo {0} levels ", levels); // Perform undo operations for (int i = 0; i < levels; i++) { if (this.current > 0) { Command command = this.commands[--this.current]; command.UnExecute(); } } } #endregion }}// Output:/*Current value = 100 (following + 100)Current value = 50 (following - 50)Current value = 500 (following * 10)Current value = 250 (following / 2)---- Undo 4 levelsCurrent value = 500 (following * 2)Current value = 50 (following / 10)Current value = 100 (following + 50)Current value = 0 (following - 100)---- Redo 3 levelsCurrent value = 100 (following + 100)Current value = 50 (following - 50)Current value = 500 (following * 10)*/

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow

这里写图片描述

发表评论

表情:
评论列表 (有 0 条评论,42人围观)

还没有评论,来说两句吧...

相关阅读