程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> .Net設計模式實例之命令模式(Command Pattern)

.Net設計模式實例之命令模式(Command Pattern)

編輯:關於.NET

一、命令模式簡介(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、源代碼

1、Command抽象類:聲明一個接口,用於執行操作

abstract class Command
{
     protected Receiver receiver;

     public Command(Receiver receiver)
     {
         this.receiver = receiver;
     }
     public abstract void Execute();
}

2、ConcreteCommand具體實現類:將一個接收者對象綁定到一個動作

class ConcreteCommand : Command
{
     // Constructor
     public ConcreteCommand(Receiver receiver)
         :base(receiver)
     {
     }
     public override void Execute()
     {
         receiver.Action();
     }
}

3、Receiver類:知道如何執行一個請求相關的操作

class Receiver
{
     public void Action()
     {
         Console.WriteLine("Called Receiver.Action()");
     }
}

4、Invoker類:要求命令執行一個請求

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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved