一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C# - C# 設計模式系列教程-命令模式

C# 設計模式系列教程-命令模式

2021-11-23 15:02Wang Juqiang C#

在軟件系統中,行為請求者與行為實現者通常是一種緊耦合的關系,但某些場合,比如需要對行為進行記錄、撤銷或重做、事務等處理時,這種無法抵御變化的緊耦合的設計就不太合適。

1. 概述

  將一個請求封裝為一個對象(即我們創建的command對象),從而使你可用不同的請求對客戶進行參數化; 對請求排隊或記錄請求日志,以及支持可撤銷的操作。

2. 解決的問題

  在軟件系統中,行為請求者與行為實現者通常是一種緊耦合的關系,但某些場合,比如需要對行為進行記錄、撤銷或重做、事務等處理時,這種無法抵御變化的緊耦合的設計就不太合適。

3. 模式中角色

  3.1 抽象命令(command):定義命令的接口,聲明執行的方法。

  3.2 具體命令(concretecommand):具體命令,實現要執行的方法,它通常是“虛”的實現;通常會有接收者,并調用接收者的功能來完成命令要執行的操作。

  3.3 接收者(receiver):真正執行命令的對象。任何類都可能成為一個接收者,只要能實現命令要求實現的相應功能。

  3.4 調用者(invoker):要求命令對象執行請求,通常會持有命令對象,可以持有很多的命令對象。這個是客戶端真正觸發命令并要求命令執行相應操作的地方,也就是說相當于使用命令對象的入口。

  3.5 客戶端(client):命令由客戶端來創建,并設置命令的接收者。

4. 模式解讀

  4.1 命令模式的類圖

C# 設計模式系列教程-命令模式

  4.2 命令模式的實現代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/// <summary>
/// 接收者類,知道如何實施與執行一個請求相關的操作,任何類都可能作為一個接收者。
/// </summary>
public class receiver
{
 /// <summary>
 /// 真正的命令實現
 /// </summary>
 public void action()
 {
  console.writeline("execute request!");
 }
}
 
/// <summary>
/// 抽象命令類,用來聲明執行操作的接口
/// </summary>
public interface icommand
{
 void execute();
}
 
/// <summary>
/// 具體命令類,實現具體命令。
/// </summary>
public class conceretecommand : icommand
{
 // 具體命令類包含有一個接收者,將這個接收者對象綁定于一個動作
 private receiver receiver;
 
 public conceretecommand(receiver receiver)
 {
  this.receiver = receiver;
 }
 
 /// <summary>
 /// 說這個實現是“虛”的,因為它是通過調用接收者相應的操作來實現execute的
 /// </summary>
 public void execute()
 {
  receiver.action();
 }
}
 
/// <summary>
/// 調度類,要求該命令執行這個請求
/// </summary>
public class invoker
{
 private icommand command;
 
 /// <summary>
 /// 設置命令
 /// </summary>
 /// <param name="command"></param>
 public void setcommand(icommand command)
 {
  this.command = command;
 }
 
 /// <summary>
 /// 執行命令
 /// </summary>
 public void executecommand()
 {
  command.execute();
 }
}

  4.3 客戶端代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class program
{
 static void main(string[] args)
 {
  receiver receiver = new receiver();
  icommand command = new conceretecommand(receiver);
  invoker invoker = new invoker();
 
  invoker.setcommand(command);
  invoker.executecommand();
 
  console.read();
 }
}

  執行結果

C# 設計模式系列教程-命令模式

  4.4 模式分析

    4.4.1 本質:對命令進行封裝,將發出命令與執行命令的責任分開。

    4.4.2 每一個命令都是一個操作:請求的一方發出請求,要求執行一個操作;接收的一方收到請求,并執行操作。

    4.4.3 請求方和接收方獨立開來,使得請求的一方不必知道接收請求的一方的接口,更不必知道請求是怎么被接收,以及操作是否被執行、何時被執行,以及是怎么被執行的。

    4.4.4 使請求本身成為一個對象,這個對象和其它對象一樣可以被存儲和傳遞。

    4.4.5 命令模式的關鍵在于引入了抽象命令接口,且發送者針對抽象命令接口編程,只有實現了抽象命令接口的具體命令才能與接收者相關聯。 

5. 模式總結

  5.1 優點

    5.1.1 解除了請求者與實現者之間的耦合,降低了系統的耦合度。

    5.1.2 對請求排隊或記錄請求日志,支持撤銷操作。

    5.1.3 可以容易地設計一個組合命令。

    5.1.4 新命令可以容易地加入到系統中。

  5.2 缺點

    5.2.1 因為針對每一個命令都需要設計一個具體命令類,使用命令模式可能會導致系統有過多的具體命令類。

  5.3 適用場景

    5.3.1 當需要對行為進行“記錄、撤銷/重做”等處理時。

    5.3.2 系統需要將請求者和接收者解耦,使得調用者和接收者不直接交互。

    5.3.3 系統需要在不同時間指定請求、請求排隊和執行請求。

    5.3.4 系統需要將一組操作組合在一起,即支持宏命令。

6. 應用舉例:銀行帳號的存款、提款

  6.1 類圖

C# 設計模式系列教程-命令模式

  6.2 代碼實現

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/// <summary>
/// 銀行帳號
/// </summary>
public class account
{
 /// <summary>
 /// 帳號總金額
 /// </summary>
 private decimal totalamount { get; set; }
 
 /// <summary>
 /// 存錢
 /// </summary>
 /// <param name="amount"></param>
 public void moneyin(decimal amount)
 {
  this.totalamount += amount;
 }
 
 /// <summary>
 /// 取錢
 /// </summary>
 /// <param name="amount"></param>
 public void moneyout(decimal amount)
 {
  this.totalamount -= amount;
 }
 
 public decimal gettotalamout()
 {
  return totalamount;
 }
}
 
public abstract class command
{
 protected account account;
 
 public command(account account)
 {
  this.account = account;
 }
 
 public abstract void execute();
}
 
/// <summary>
/// 存款命令
/// </summary>
public class moneyincommand : command
{
 private decimal amount;
 
 public moneyincommand(account account, decimal amount)
  : base(account)
 {
  this.amount = amount;
 }
 
 /// <summary>
 /// 實現存錢命令
 /// </summary>
 public override void execute()
 {
  account.moneyin(amount);
 }
}
 
/// <summary>
/// 取款命令類
/// </summary>
public class moneyoutcommand : command
{
 private decimal amount;
 public moneyoutcommand(account account, decimal amount)
  : base(account)
 {
  this.amount = amount;
 }
 
 /// <summary>
 /// 實現取錢命令
 /// </summary>
 public override void execute()
 {
  account.moneyout(amount);
 }
}
 
public class invoker
{
 private command command;
 
 public void setcommand(command command)
 {
  this.command = command;
 }
 
 public void executecommand()
 {
  command.execute();
 }
}

  6.3 客戶端代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class program
{
 static void main(string[] args)
 {
  // 創建銀行帳號
  account account = new account();
  // 創建一個存入500元的命令
  command commandin = new moneyincommand(account,500);
  // 創建一個調度者
  bankaccount.invoker invoker = new bankaccount.invoker();
 
  // 設置存錢命令
  invoker.setcommand(commandin);
  // 執行
  invoker.executecommand();
  console.writeline("the current amount is " + account.gettotalamout().tostring("n2"));
 
  // 再次存入500
  command commandin2 = new moneyincommand(account, 500);
  invoker.setcommand(commandin2);
  invoker.executecommand();
  console.writeline("the current amount is " + account.gettotalamout().tostring("n2"));
 
  // 取出300
  command commandout = new moneyoutcommand(account, 300);
  invoker.setcommand(commandout);
  invoker.executecommand();
  console.writeline("the current amount is " + account.gettotalamout().tostring("n2"));
 
  console.read();
 }
}

 

  執行結果

C# 設計模式系列教程-命令模式

以上就是本文的全部內容,希望能給大家一個參考,也希望大家多多支持服務器之家。

延伸 · 閱讀

精彩推薦
  • C#C#通過KD樹進行距離最近點的查找

    C#通過KD樹進行距離最近點的查找

    這篇文章主要為大家詳細介紹了C#通過KD樹進行距離最近點的查找,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    帆帆帆6112022-01-22
  • C#C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    這篇文章主要介紹了C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題,簡單描述了訪問者模式的定義并結合具體實例形式分析了C#使用訪問者模式解決長...

    GhostRider9502022-01-21
  • C#C#裁剪,縮放,清晰度,水印處理操作示例

    C#裁剪,縮放,清晰度,水印處理操作示例

    這篇文章主要為大家詳細介紹了C#裁剪,縮放,清晰度,水印處理操作示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    吳 劍8332021-12-08
  • C#Unity3D實現虛擬按鈕控制人物移動效果

    Unity3D實現虛擬按鈕控制人物移動效果

    這篇文章主要為大家詳細介紹了Unity3D實現虛擬按鈕控制人物移動效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一...

    shenqingyu060520232410972022-03-11
  • C#深入解析C#中的交錯數組與隱式類型的數組

    深入解析C#中的交錯數組與隱式類型的數組

    這篇文章主要介紹了深入解析C#中的交錯數組與隱式類型的數組,隱式類型的數組通常與匿名類型以及對象初始值設定項和集合初始值設定項一起使用,需要的...

    C#教程網6172021-11-09
  • C#C#實現XML文件讀取

    C#實現XML文件讀取

    這篇文章主要為大家詳細介紹了C#實現XML文件讀取的相關代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    Just_for_Myself6702022-02-22
  • C#WPF 自定義雷達圖開發實例教程

    WPF 自定義雷達圖開發實例教程

    這篇文章主要介紹了WPF 自定義雷達圖開發實例教程,本文介紹的非常詳細,具有參考借鑒價值,需要的朋友可以參考下...

    WinterFish13112021-12-06
  • C#C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    這篇文章主要介紹了C# 實現對PPT文檔加密、解密及重置密碼的操作方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下...

    E-iceblue5012022-02-12
主站蜘蛛池模板: 精品国产成人 | 国产盗摄美女嘘嘘视频 | 美女厕所尿尿擦逼 | 亚洲精品视频在线免费 | 亚洲国产成人在线视频 | 国产一区二区在线看 | 欧洲久久| 美女伊人网 | 日韩视频一区二区三区 | 日本视频免费在线观看 | 国产福利不卡 | 天选之王漫画顾长歌免费阅读 | 5g影院天天爽 | 美女用屁股把人吞进肚子 | 免费看伦理片 | 精品午夜中文字幕熟女人妻在线 | 日本中文字幕二区三区 | 99久久精品99999久久 | melody中文字幕 | 母性本能在线观看 | 色婷综合 | 成熟女人50岁一级毛片不卡 | 亚飞与亚基国语1080p在线观看 | 操尼姑| 日本无遮挡拍拍拍凤凰 | 亚洲精品在线免费看 | 特黄一级大片 | 久久中文骚妇内射 | 污小说h | ova巨公主催眠1在线观看 | 亚洲欧美午夜 | 男女发生性关系视频 | 国产成人精品在线观看 | 成年私人影院免费视频网站 | 97就去干 | 羞羞在线观看 | 国产午夜免费视频 | 国产女乱淫真高清免费视频 | 国产亚洲精品91 | 欧美成人aa久久狼窝动画 | 亚洲精品无码不卡 |