通俗易懂設計模式解析——命令模式

  • 2019 年 10 月 3 日
  • 筆記

前言

  今天我們一起來看行為型設計模式中的命令模式、何為命令模式呢?先談命令——我現在需要對某一條信息進行刪除,我進行點擊刪除按鈕。後台執行刪除的命令、對信息進行刪除。那麼我們要講的命令模式又是什麼呢?命令模式就是把一個操作或者行為抽象為一個對象。然後通過對命令的抽象化來使得發出命令的職責和執行命令的職責分隔開。簡單來說命令模式就是解決命令的請求者和命令的執行者之間的耦合關係的。

命令模式介紹

一、來由

  在我們開發軟件系統的時候,命令的請求者和命令的執行者是屬於緊耦合的狀態。但是對於某些特殊場合這麼一種緊耦合的狀態就不合適了。例如對行為命令的”日誌記錄、撤銷/恢復、命令的隊列”等操作就不太合適了。那麼在這些情況下如何對這些命令進行統一的管理呢?實現其松耦合呢?

二、意圖

  將一個請求封裝成一個對象,從而使您可以用不同的請求對客戶進行參數化。

三、案例圖

 

四、命令模式代碼示例

我們看上面的案例圖可以看到命令模式是包含了以下五個部分的:

客戶角色:創建具體的命令對象並確定命令對象的接收者

命令請求者:命令模式中最重要的角色、持有命令對象、實現對命令的控制、要求命令對象執行請求

命令接收者:真正的命令的執行者、實現具體功能

命令角色:聲明所有的命令的一個抽象類

具體命令角色:命令接口實現對象、持有命令接收者、調用接收者完成命令的執行

在我們日常軟件開發過程中必定會涉及到信息的增刪改查、一般的信息進行操作也就罷了。但是對於一些重要的信息進行操作的時候我們是否就需要對其進行控制了。比如對其操作的日誌的記錄。對操作命令的撤銷恢復。這裡我們看看如何使用命令模式來對命令進行控制操作:

 

namespace Command_Pattern  {      class CommandPattern      {      }      #region 命令接收者——具體操作 ===================      /// <summary>      /// 執行命令      /// </summary>      public class InfoReceiver      {          public void Delete()          {              Console.WriteLine("刪除了第一條信息!");          }          public void Update()          {              Console.WriteLine("更新了第二天信息!");          }      }      #endregion        #region 命令請求者——控制命令 ===================      /// <summary>      /// 控制命令調用請求      /// </summary>      public class InfoInvoke      {          /// <summary>          /// 記錄上一個命令          /// </summary>          private Command lastCommand =null;          /// <summary>          /// 接收當前命令          /// </summary>          private Command _command = null;          public InfoInvoke(Command command=null)          {              this._command = command;          }          public string ExecuteInvoke()          {              if (_command==null&& lastCommand==null)                  return ("無命令執行!");              if (_command == null)              {                  Console.WriteLine($"記錄此操作記錄{_command.GetType().Name}的撤銷操作!");                  _command = lastCommand;                  return ("執行撤銷操作!");              }              Console.WriteLine($"記錄此操作記錄{_command.GetType().Name}!");              _command.Execute();              return ("執行成功!");          }      }      #endregion        #region 命令角色——抽象命令 =====================      /// <summary>      /// 抽象命令 持有命令接收者,調用接收者執行命令      /// </summary>      public abstract class Command      {          protected InfoReceiver _infoReceiver;          public Command(InfoReceiver infoReceiver)          {              this._infoReceiver = infoReceiver;          }          public abstract void Execute();      }      #endregion        #region 具體命令角色——調用接收者 ===============      /// <summary>      /// 實現抽象角色      /// </summary>      public class InfoCommandDelete : Command      {          public InfoCommandDelete(InfoReceiver infoReceiver) : base(infoReceiver) { }          public override void Execute()          {              _infoReceiver.Delete();          }      }      #endregion        #region 具體命令角色——調用接收者 ===============      /// <summary>      /// 實現抽象角色      /// </summary>      public class InfoCommandUpdate : Command      {          public InfoCommandUpdate(InfoReceiver infoReceiver) : base(infoReceiver) { }          public override void Execute()          {              _infoReceiver.Update();          }      }      #endregion  }

 

namespace Command_Pattern  {      class Program      {          static void Main(string[] args)          {              ///初始化命令接收者和命令請求者還有具體命令              InfoReceiver infoReceiver = new InfoReceiver();                InfoCommandDelete infoCommandDelete = new InfoCommandDelete(infoReceiver);                InfoInvoke infoInvoke = new InfoInvoke(infoCommandDelete);              var result=infoInvoke.ExecuteInvoke();                Console.WriteLine(result);            }      }  }

 

使用場景及優缺點

在命令模式中重點就是實現將“行為請求者”和“行為實現者”之間進行解耦。而在命令請求者角色中可以對具體命令角色做一定的控制、同時也可以保存其額外的狀態信息。

一、使用場景

1、認為是命令的地方都可以使用命令模式

2、系統支持命令的撤銷/恢復、重新執行等操作的時候可以考慮使用命令模式

3、命令的發送者和命令執行者有不同的生命周期,不要求命令發送必須立馬執行

4、命令需要進行管理控制時

二、優點

1、降低了系統的耦合性

2、新的命令可以很容易添加到系統中

3、可以將命令組合在一起形成合成命令

4、可以設計實現撤銷、重新執行的操作

三、缺點

1、使用命令模式可能導致有過多的具體命令類、這樣會使系統變得不切實際。

總結

  到這裡我們就介紹完了命令模式。總的來說命令模式是將”行為請求者”和”行為實現者”進行了解耦。解耦之後就方便對命令進行控制管理(操作信息日誌記錄、撤銷/恢復操作、重新操作、命令隊列等等)。同時對新的命令加入也方便了一些(方便對命令擴展)。


 

   一個人如若不能使自己的人生輝煌,但也沒有理由使它黯淡;人生可以平凡,但不可以庸俗、墮落;人生不在乎掠取多少,而在於追求過程的完美與卓越!

     C#設計模式系列目錄

     歡迎大家掃描下方二維碼,和我一起踏上設計模式的闖關之路吧!