欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
命令模式(Command Pattern)

一、 命令(Command)模式

命令(Command)模式屬于對象的行為模式【GOF95】。命令模式又稱(chēng)為行動(dòng)(Action)模式或交易(Transaction)模式。命令模式把一個(gè)請求或者操作封裝到一個(gè)對象中。命令模式允許系統使用不同的請求把客戶(hù)端參數化,對請求排隊或者記錄請求日志,可以提供命令的撤銷(xiāo)和恢復功能。

命令模式是對命令的封裝。命令模式把發(fā)出命令的責任和執行命令的責任分割開(kāi),委派給不同的對象。

每一個(gè)命令都是一個(gè)操作:請求的一方發(fā)出請求要求執行一個(gè)操作;接收的一方收到請求,并執行操作。命令模式允許請求的一方和接收的一方獨立開(kāi)來(lái),使得請求的一方不必知道接收請求的一方的接口,更不必知道請求是怎么被接收,以及操作是否被執行、何時(shí)被執行,以及是怎么被執行的。


二、 命令模式的結構

命令模式的類(lèi)圖如下:

 

命令模式涉及到五個(gè)角色,它們分別是:

  • 客戶(hù)(Client)角色:創(chuàng )建了一個(gè)具體命令(ConcreteCommand)對象并確定其接收者。
  • 命令(Command)角色:聲明了一個(gè)給所有具體命令類(lèi)的抽象接口。這是一個(gè)抽象角色。
  • 具體命令(ConcreteCommand)角色:定義一個(gè)接受者和行為之間的弱耦合;實(shí)現Execute()方法,負責調用接收考的相應操作。Execute()方法通常叫做執方法。
  • 請求者(Invoker)角色:負責調用命令對象執行請求,相關(guān)的方法叫做行動(dòng)方法。
  • 接收者(Receiver)角色:負責具體實(shí)施和執行一個(gè)請求。任何一個(gè)類(lèi)都可以成為接收者,實(shí)施和執行請求的方法叫做行動(dòng)方法。

 

三、 命令模式的示意性源代碼

 

 

// Command pattern -- Structural example  
using System;

// "Command"
abstract class Command
{
  
// Fields
  protected Receiver receiver;

  
// Constructors
  public Command( Receiver receiver )
  
{
    
this.receiver = receiver;
  }


  
// Methods
  abstract public void Execute();
}


// "ConcreteCommand"
class ConcreteCommand : Command
{
  
// Constructors
  public ConcreteCommand( Receiver receiver ) :
    
base ( receiver ) {}

  
// Methods
  public override void Execute()
  
{
    receiver.Action();
  }

}


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

}


// "Invoker"
class Invoker
{
  
// Fields
  private Command command;

  
// Methods
  public void SetCommand( Command command )
  
{
    
this.command = command;
  }


  
public void ExecuteCommand()
  
{
    command.Execute();
  }

}


/// 
///  Client test
/// 

public class Client
{
  
public static void Main( string[] args )
  
{
    
// Create receiver, command, and invoker
    Receiver r = new Receiver();
    Command c 
= new ConcreteCommand( r );
    Invoker i 
= new Invoker();

    
// Set and execute command
    i.SetCommand(c);
    i.ExecuteCommand();
  }

}

 

 

四、 玉帝傳美猴王上天

命令模式不是新的發(fā)明,在美猴王大鬧天宮之前就有了。那時(shí)玉帝命令太白金星召美猴王上天:"金星徑入(水簾洞)當中,面南立定道:‘我是西方太白金星,奉玉帝招安圣旨,下界請你上大,拜受仙錄?!?玉帝是系統的客戶(hù)端,太白金星是命令的發(fā)出者,猴王是命令的接收者,圣旨就是命令。玉帝的這一道命令就是要求猴王到上界報到。玉帝只管發(fā)出命令,而不管命令是怎樣傳達到美猴王的。太白金星負責將圣旨傳到,可是美猴王怎么執行圣旨、何時(shí)執行圣旨是美猴王自己的事。果不然,個(gè)久美猴王就大鬧了天宮。

這個(gè)模擬系統的設計如下:

 


五、 命令模式的實(shí)現

首先命令應當"重"一些還是"輕"一些。在不同的情況下,可以做不同的選擇。如果把命令設計得"輕",那么它只是提供了一個(gè)請求者和接收者之間的耦合而己,命令代表請求者實(shí)現請求。

相反,如果把命令設計的"重",那么它就應當實(shí)現所有的細節,包括請求所代表的操作,而不再需要接收者了。當一個(gè)系統沒(méi)有接收者時(shí),就可以采用這種做法。

更常見(jiàn)的是處于最"輕"和最"重"的兩個(gè)極端之間時(shí)情況。命令類(lèi)動(dòng)態(tài)地決定調用哪一個(gè)接收者類(lèi)。

其次是否支持undo和redo。如果一個(gè)命令類(lèi)提供一個(gè)方法,比如叫unExecute(),以恢復其操作的效果,那么命令類(lèi)就可以支持undo和redo。具體命令類(lèi)需要存儲狀態(tài)信息,包括:

1. 接收者對象實(shí)際上實(shí)施請求所代表的操作;
2. 對接收者對象所作的操作所需要的參數;
3. 接收者類(lèi)的最初的狀態(tài)。接收者必須提供適當的方法,使命令類(lèi)可以通過(guò)調用這個(gè)方法,以便接收者類(lèi)恢復原有狀態(tài)。

如果只需要提供一層的undo和redo,那么系統只需要存儲最后被執行的那個(gè)命令對象。如果需要支持多層的undo和redo,那么系統就需要存儲曾經(jīng)被執行過(guò)的命令的清單,清單能允許的最大的長(cháng)度便是系統所支持的undo和redo的層數。沿著(zhù)清單逆著(zhù)執行清單上的命令的反命令(unExecute())便是undo;沿著(zhù)清單順著(zhù)執行清單上的命令便是redo。


六、 命令模式的實(shí)際應用案例

下面的代碼使用命令模式演示了一個(gè)簡(jiǎn)單的計算器,并允許執行undo與redo。注意:"operator"在C#中是關(guān)鍵詞,所以在前面添加一個(gè)"@"將其變?yōu)闃俗R符。

 

// Command pattern -- Real World example  
using System;
using System.Collections;

// "Command"
abstract class Command
{
  
// Methods
  abstract public void Execute();
  
abstract public void UnExecute();
}


// "ConcreteCommand"
class CalculatorCommand : Command
{
  
// Fields
  char @operator;
  
int operand;
  Calculator calculator;

  
// Constructor
  public CalculatorCommand( Calculator calculator,
    
char @operatorint operand )
  
{
    
this.calculator = calculator;
    
this.@operator = @operator;
    
this.operand = operand;
  }


  
// Properties
  public char Operator
  
{
    
set{ @operator = value; }
  }


  
public int Operand
  
{
    
set{ operand = value; }
  }


  
// Methods
  override public void Execute()
  
{
    calculator.Operation( @
operator, operand );
  }

 
  
override public void UnExecute()
  
{
    calculator.Operation( Undo( @
operator ), operand );
  }


  
// Private helper function
  private char Undo( char @operator )
  
{
    
char undo =  ;
    
switch( @operator )
    
{
      
case +: undo = -break;
      
case -: undo = +break;
      
case *: undo = /break;
      
case /: undo = *break;
    }

    
return undo;
  }

}


// "Receiver"
class Calculator
{
  
// Fields
  private int total = 0;

  
// Methods
  public void Operation( char @operatorint operand )
  
{
    
switch( @operator )
    
{
      
case +: total += operand; break;
      
case -: total -= operand; break;
      
case *: total *= operand; break;
      
case /: total /= operand; break;
    }

    Console.WriteLine( 
"Total = {0} (following {1} {2})",
      total, @
operator, operand );
  }

}


// "Invoker"
class User
{
  
// Fields
  private Calculator calculator = new Calculator();
  
private ArrayList commands = new ArrayList();
  
private int current = 0;

  
// Methods
  public void Redo( int levels )
  
{
    Console.WriteLine( 
"---- Redo {0} levels ", levels );
    
// Perform redo operations
    forint i = 0; i < levels; i++ )
      
if( current < commands.Count - 1 )
        ((Command)commands[ current
++ ]).Execute();
  }


  
public void Undo( int levels )
  
{
    Console.WriteLine( 
"---- Undo {0} levels ", levels );
    
// Perform undo operations
    forint i = 0; i < levels; i++ )
      
if( current > 0 )
        ((Command)commands[ 
--current ]).UnExecute();
  }


  
public void Compute( char @operatorint 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
++;
  }

}


/// 
/// CommandApp test
/// 

public class Client
{
  
public static void Main( string[] args )
  
{
    
// Create user and let her compute
    User user = new User();

    user.Compute( 
+100 );
    user.Compute( 
-50 );
    user.Compute( 
*10 );
    user.Compute( 
/2 );

    
// Undo and then redo some commands
    user.Undo( 4 );
    user.Redo( 
3 );
  }

}

 

 


七、 在什么情況下應當使用命令模式

在下面的情況下應當考慮使用命令模式:

1、使用命令模式作為"CallBack"在面向對象系統中的替代。"CallBack"講的便是先將一個(gè)函數登記上,然后在以后調用此函數。

2、需要在不同的時(shí)間指定請求、將請求排隊。一個(gè)命令對象和原先的請求發(fā)出者可以有不同的生命期。換言之,原先的請求發(fā)出者可能已經(jīng)不在了,而命令對象本身仍然是活動(dòng)的。這時(shí)命令的接收者可以是在本地,也可以在網(wǎng)絡(luò )的另外一個(gè)地址。命令對象可以在串形化之后傳送到另外一臺機器上去。

3、系統需要支持命令的撤消(undo)。命令對象可以把狀態(tài)存儲起來(lái),等到客戶(hù)端需要撤銷(xiāo)命令所產(chǎn)生的效果時(shí),可以調用undo()方法,把命令所產(chǎn)生的效果撤銷(xiāo)掉。命令對象還可以提供redo()方法,以供客戶(hù)端在需要時(shí),再重新實(shí)施命令效果。

4、如果一個(gè)系統要將系統中所有的數據更新到日志里,以便在系統崩潰時(shí),可以根據日志里讀回所有的數據更新命令,重新調用Execute()方法一條一條執行這些命令,從而恢復系統在崩潰前所做的數據更新。

5、一個(gè)系統需要支持交易(Transaction)。一個(gè)交易結構封裝了一組數據更新命令。使用命令模式來(lái)實(shí)現交易結構可以使系統增加新的交易類(lèi)型。


八、 使用命令模式的優(yōu)點(diǎn)和缺點(diǎn)

命令允許請求的一方和接收請求的一方能夠獨立演化,從而且有以下的優(yōu)點(diǎn):

  • 命令模式使新的命令很容易地被加入到系統里。
  • 允許接收請求的一方?jīng)Q定是否要否決(Veto)請求。
  • 能較容易地設計-個(gè)命令隊列。
  • 可以容易地實(shí)現對請求的Undo和Redo。
  • 在需要的情況下,可以較容易地將命令記入日志。
  • 命令模式把請求一個(gè)操作的對象與知道怎么執行一個(gè)操作的對象分割開(kāi)。
  • 命令類(lèi)與其他任何別的類(lèi)一樣,可以修改和推廣。
  • 你可以把命令對象聚合在一起,合成為合成命令。比如宏命令便是合成命令的例子。合成命令是合成模式的應用。
  • 由于加進(jìn)新的具體命令類(lèi)不影響其他的類(lèi),因此增加新的具體命令類(lèi)很容易。

命令模式的缺點(diǎn)如下:

  • 使用命令模式會(huì )導致某些系統有過(guò)多的具體命令類(lèi)。某些系統可能需要幾十個(gè),幾百個(gè)甚至幾千個(gè)具體命令類(lèi),這會(huì )使命令模式在這樣的系統里變得不實(shí)際。
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
命令模式——行為型模式(2)
設計模式之命令模式(三)
C#設計模式學(xué)習筆記:(14)命令模式
從Undo,Redo談命令模式
Command 模式在 SAP Spartacus 中的具體應用一例
(swing讀書(shū)筆記)Undo/Redo(下)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久