設計模式(六):控制臺中的“命令模式”(Command Pattern)

来源:http://www.cnblogs.com/ludashi/archive/2016/04/26/5396571.html
-Advertisement-
Play Games

今天的博客中就來系統的整理一下“命令模式”。說到命令模式,我就想起了控制台(Console)中的命令。無論是Windows操作系統(cmd.exe)還是Linux操作系統(命令行式shell(Command Line Interface shell ,即CLI shell)都有命令行程式。說白了就是 ...


今天的博客中就來系統的整理一下“命令模式”。說到命令模式,我就想起了控制台(Console)中的命令。無論是Windows操作系統(cmd.exe)還是Linux操作系統(命令行式shell(Command Line Interface shell ,即CLI shell)都有命令行程式。說白了就是你輸入你要執行的命令提示符,然後電腦就還是根據你所下達的命令來執行。你最終看到的是命令執行後的結果,具體的執行細節不需要你一步步的去下達命令。(與之前博客保持一致,我們仍然使用Swift語言來進行實現)

進一步說,你下達的命令是一個總的命令,而電腦執行時是講該命令分為不同的階段來執行的。舉個簡單的例子,當你打開電腦是,你只需按一下開機鍵,也就是下達你的Start命令。此時電腦收都命令後就會執行硬碟啟動、點亮屏幕、載入系統等等一系列的操作,而這些操作都是你下達Start命令後其自動完成的。再比如,你使用Linux系統下的Shell時,你會在Shell中輸入各種命令,然後電腦就會根據你的命令來執行系列的操作,具體哪些操作是對外隱藏的。這也就是對具體的實現細節進行了封裝,並對外留出調用介面

看完上面的描述,是時候回到今天的主題“命令模式”上了。命令模式簡單的說就是將一些列的命令(函數或者方法)進行封裝,隱藏內部執行細節,並對外留出調用的介面。命令模式是支持撤銷操作的,撤銷所做的事情就是與你剛纔下達的命令相反。下方就是命令模式的定義了,說白了命令模式就是進一步對命令進行封裝,簡化命令的執行。這些命令在編程中就是一個個的函數。也可以說“命令模式”是對函數調用的封裝,簡化了函數調用的方式,隱藏了函數調用的細節。

命令模式:請求封裝成對象,以便使用不同的請求、隊列或者日誌來參數化其他對象。命令模式也支持可撤銷的操作。

今天博客中會通過命令模式來實現控制台是示例,也就是我們可以通過給控制臺下達不同的命令來進行不同的操作。

 

一、控制台命令模式的類圖

下方就是我們將要實現的控制台“命令模式”的示例的類圖。下方的類圖還是比較簡單的,紅框上方是具體的類(電腦和電燈)。這些具體的類中有屬於自己的不同的命令(對應著不同的函數函數),比如Computer類(電腦)中有Start、ScreenLight、Load、StartOver、Off等命令,而Light(電燈)類中有On、Off命令。

而紅框中是我們示例的核心,也就是對命令的上述具體命令的封裝。在封裝命令時我們會實現一個介面(該示例中是Command協議),該介面就是外部執行命令( execute() 函數)的介面。封裝的不同的命令都會遵循Command協議,所以我們封裝的命令都會對外暴漏一個execute()函數,用來執行我們封裝的命令。在封裝命令時,我們會根據封裝的命令的特點來執行特定的命令。比如下方的ComputerStartCommand命令中的就會包括Start、ScreenLight、Load、StartOver等子命令。也就是說在ComputerStartCommand命令中調用了Computer中的部分命令(函數),也就是對Computer類中的函數的調用做了進一步的封裝,所以ComputerStartCommand命令要依賴於Computer類的。

紅框下方就是我們的Console(控制台)類,Console是依賴於命令的介面而不依賴於命令的具體實現,這對模塊間的解耦是非常有用的。在Console類中的command屬性就是我們所依賴的命令介面,我們可以給command賦值不同的具體命令的實現,然後在Action函數中去執行具體的命令。請參加下方的類圖。

    

 

二、根據上述類圖進行代碼實現

上一部分對類圖進了詳細的介紹,接下來我們對上述類圖進行代碼實現就不是什麼難事了。我們實現的步驟是與上面分析的步驟是一致的,自上而下。首先我們會給出Computer與Light的實現,然後是紅框中的命令集合的實現,最後是Console的實現。如下所示:

1、具體命令執行對象的實現

首先我們要對真正去執行命令的對象進行代碼實現,在該實例中就是Computer類和Light類。當然從上述示例中,我們不難看出這兩個類要包括哪些命令(方法)。下方就是我們Computer類和Light類的具體實現,因為代碼較為簡單,在此就不做過多的贅述了。具體代碼實現如下所示:

    

 

2.對上述設備的命令進行封裝

下方代碼段就是上面類圖中的紅框部分的代碼的具體實現。我們將Command聲明為協議(命令對外的介面),而LightOnCommand、LightOffCommand、ComputerStartCommand具體的命令集合都遵循與這個協議。也就是說著三種不同的命令實現對外都有統一的介面,LightOnCommand與LightOffCommand都依賴於Light類,並且根據自己的命令種類來調用Light不同的方法,這也符合面向對象設計的單一職責。ComputerStartCommand命令類則依賴於Compute外設,會調用Computer中與啟動相關的具體子命令。具體代碼如下所示:

   

 

3. 控制台的具體實現

上面我們實現了類圖上面的兩個模塊,緊接著我們要實現類圖最下方的那個類,也就是Console類。Console類也是比較簡單的,Console類依賴於Command介面,其中的command存儲屬性就是用來存儲那些遵循Command協議的類的對象的。在Console類中的action()方法是用來執行命令的。具體實現如下。

    

 

三、測試用例

經過上面的類圖的介紹與具體的代碼實現,相比對“命令模式”有點概念了吧。最後一部分我們要對上述代碼的實現進行測試,看一下我們的代碼實現是否有問題。下方代碼截圖就是我們的測試用例以及該測試用例執行後輸出的結果。首先我們創建了一個控制台的對象(類似於我們打開了一個Shell視窗),然後輸出不同的命令(setCommand()),最後進行執行(調用action())。測試用例具體如下所示:

   

 

至此我們的“命令模式”的一個完整示例就執行完了,最後用一句話來總結一下命令模式,那就是“命令模式是對一些列函數的調用的封裝,然後留出執行的介面”。

同樣今天的Demo也會在github上進行分享,分享地址為:https://github.com/lizelu/DesignPatterns-Swift


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • tomcat是一個開源軟體,是由java語言編寫的,它工作的話需要運行在jvm虛擬機中,說到jvm不得不說下java這個大名鼎鼎的編程語言了 java這個編程語言最優秀的特點要數write once , run anywhere 額!怎麼聽起來有點流氓的感覺 沒錯,而這全是依賴於jvm這個虛擬機,使 ...
  • Ubuntu14.04 Tomcat 安裝過程記錄 檢查java的版本 zhousp@ubuntu:~$ sudo java -version [sudo] password for zhousp: java version "1.7.0_95" OpenJDK Runtime Environmen ...
  • 版權聲明 版權聲明:原創文章 禁止轉載 請通過右側公告中的“聯繫郵箱([email protected])”聯繫我 勿用於學術性引用。 勿用於商業出版、商業印刷、商業引用以及其他商業用途。 本文不定期修正完善。 本文鏈接:http://www.cnblogs.com/wlsandwho/p/ ...
  • 第三章 Git使用入門 使用Git的目的是減少各種版本的Linux的壓縮大小,提供源代碼在Linux上進行編譯。 在這一個章節中,其實就是關鍵步驟的操作,雖然Git與我們學習的android沒有很大的聯繫,但是在開發環境中也是必不可少的。通過學習這個章節,學習到了安裝,查看,提取Git的方法。下麵將 ...
  • 狀態模式:當一個對象的內在狀態改變時,允許改變其行為,這個對象看起來像是改變了其類。 狀態模式主要解決的是當控制一個對象狀態轉換的條件表達式過於複雜時情況,把狀態的判斷邏輯轉移到表示不同狀態的一系列類當中,可以把複雜的判斷邏輯簡化。 下麵舉例說明,假設有兩種狀態需要轉換,每請求一次就轉換一次狀態: ...
  • 今天在mac os 上編譯安裝Nginx時候,報錯:ld: symbol(s) not found for architecture x86_64, 經過一番折騰之後發現,由於Nginx依賴openssl庫,查看openssl的./config 文件發現,這個問題應該是 openssl/config ...
  • Atitit.增強系統穩定性 虛擬記憶體的設置 1.1. 讀取虛擬記憶體配置1 1.2. 禁止虛擬記憶體1 1.3. 預設所有驅動器虛擬記憶體1 1.4. 設置c d盤虛擬記憶體為系統管理1 1.5. 設置d盤大小2g--3g1 1.1. 讀取虛擬記憶體配置 [HKEY_LOCAL_MACHINE\SYSTEM ...
  • 複雜的軟體必須有清晰合理的架構,否則無法開發和維護。 MVC(Model-View-Controller)是最常見的軟體架構之一,業界有著廣泛應用。它本身很容易理解,但是要講清楚,它與衍生的 MVP 和 MVVM 架構的區別就不容易了。 (題圖:攝於瓦倫西亞,西班牙,2014年8月) 一、MVC M ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...