1. 程式人生 > >命令模式,資料庫事務,命令的撤銷恢復

命令模式,資料庫事務,命令的撤銷恢復

命令模式(COMMAND),又稱動作(Action),事務(Transaction),通過將一個請求封裝為一個物件,從而使你可用不同的請求對客戶進行引數化,實現對請求排隊或記錄請求日誌,以及支援可撤銷的操作。命令模式可以將請求傳送者和接收者完全解耦,傳送者與接收者之間沒有直接引用關係,傳送請求的物件只需要知道如何傳送請求,而不必知道如何完成請求。

一、使用場景

1、需要抽象出待執行的動作以引數化某物件時。這種引數化機制在過程語言中是通過回撥函式表示式實現的,Command模式則是回撥機制的一個面向物件的替代品。

2、在不同的時刻指定、排列和執行請求。一個Command物件可以有一個與初始請求無關的生存期,你完全可以將請求的命令物件傳遞給另一個不同的程序並在那實現該請求。

3、支援取消操作。在Command的execute操作執行前將狀態儲存到一個歷史列表中,通過向後和向前遍歷該列表並分別呼叫undo和redo方法來實現數量不限的“取消”和"重做"。

4、支援修改日誌,當系統崩潰時可以用於修改的重做,以便復原崩潰前狀態。在Command介面中可以加入裝載和儲存操作,用來將系統修改持久化到日誌檔案。系統恢復只需從日誌檔案中讀入修改記錄,然後使用Command的execute重新執行它們即可。

5、用構建在原語操作上的高層操作構造一個系統,比如支援事務的資訊系統。一個事務封裝了對資料的一組變動,Command模式提供了對事務進行建模的方法。Command提供的公共的介面,可以用來以一致的方式呼叫所有事務。同時使用命令模式也易於新增新事務以擴充套件系統。

二、UML圖

命令模式uml

注:   命令模式的關鍵在於引入了抽象命令類,請求傳送者針對抽象命令類程式設計,只有實現了抽象命令類的具體命令才與請求接收者相關聯。

三、Java實現

  1. package study.patterns.command;  
  2. import java.util.ArrayList;  
  3. import java.util.List;  
  4. /** 
  5.  * 命令模式的本質是對請求進行封裝,一個請求對應於一個命令,將發出命令的責任和執行命令的責任分割開。 
  6.  * 每一個命令都是一個操作:請求的一方發出請求要求執行一個操作;接收的一方收到請求,並執行相應的操作。 
  7.  * 命令模式允許請求的一方和接收的一方獨立開來,使得請求的一方不必知道接收請求的一方的介面,
     
  8.  * 更不必知道請求如何被接收、操作是否被執行、何時被執行,以及是怎麼被執行的。 
  9.  * @author qbg 
  10.  */
  11. publicclass CommandPattern {  
  12.     publicstaticvoid main(String[] args) {  
  13.         //請求接收者(ReceiverA)封裝到具體的命令物件(ConcreteCommandA)中,與請求傳送者(CommandPattern)分離。
  14.         Command comA = new ConcreteCommandA();  
  15.         Command comB = new ConcreteCommandB();  
  16.         Command macro = new MacroCommand();  
  17.         macro.addCommand(comA);  
  18.         macro.addCommand(comB);  
  19.         macro.execute();  
  20.         macro.undo();  
  21.         macro.redo();  
  22.         macro.writeLog("config.log");  
  23.         macro.readLog("config.log");  
  24.     }  
  25. }  
  26. /** 
  27.  * 抽象命令:採用組合模式實現巨集命令(類似於批處理命令,可以執行一批命令)  
  28.  */
  29. interface Command{  
  30.     /** 
  31.      * 新增命令(組合模式) 
  32.      * @param command 
  33.      */
  34.     publicvoid addCommand(Command command);  
  35.     /** 
  36.      * 刪除命令(組合模式) 
  37.      * @param command 
  38.      */
  39.     publicvoid removeCommand(Command command);  
  40.     /** 
  41.      * 撤銷(撤銷上次操作) 
  42.      */
  43.     publicvoid undo();  
  44.     /** 
  45.      * 重做(重做上次操作) 
  46.      */
  47.     publicvoid redo();  
  48.     /** 
  49.      * 執行命令 
  50.      */
  51.     publicvoid execute();  
  52.     /** 
  53.      * 從指定檔案讀取執行命令,以待重新執行 
  54.      * @param fileName 
  55.      */
  56.     publicvoid readLog(String fileName);  
  57.     /** 
  58.      * 將執行過的命令持久化檔案中,以待災難恢復 
  59.      * @param fileName 
  60.      */
  61.     publicvoid writeLog(String fileName);  
  62. }  
  63. /** 
  64.  * 預設實現類,不提供任何實現  
  65.  */
  66. class DefaultCommand implements Command{  
  67.     @Override
  68.     publicvoid addCommand(Command command) {  
  69.         thrownew IllegalAccessError("方法未實現");  
  70.     }  
  71.     @Override
  72.     publicvoid removeCommand(Command command) {  
  73.         thrownew IllegalAccessError("方法未實現");  
  74.     }  
  75.     @Override
  76.     publicvoid undo() {  
  77.         thrownew IllegalAccessError("方法未實現");  
  78.     }  
  79.     @Override
  80.     publicvoid redo() {  
  81.         thrownew IllegalAccessError("方法未實現");  
  82.     }  
  83.     @Override
  84.     publicvoid execute() {  
  85.         thrownew IllegalAccessError("方法未實現");  
  86.     }  
  87.     @Override
  88.     publicvoid readLog(String fileName) {  
  89.         thrownew IllegalAccessError("方法未實現");  
  90.     }  
  91.     @Override
  92.     publicvoid writeLog(String fileName) {  
  93.         thrownew IllegalAccessError("方法未實現");  
  94.     }  
  95. }  
  96. /** 
  97.  * 命令接收者A,具體業務處理  
  98.  */
  99. class ReceiverA{  
  100.     publicvoid action(){  
  101.         System.out.println("ReceiverA:do something....");  
  102.     }  
  103. }  
  104. /** 
  105.  * 命令接收者B,具體業務處理  
  106.  */
  107. class ReceiverB{  
  108.     publicvoid action(){  
  109.         System.out.println("ReceiverB:do something....");  
  110.     }  
  111. }  
  112. /** 
  113.  * 具體命令實現,覆蓋預設命令類的execute() 
  114.  */
  115. class ConcreteCommandA extends DefaultCommand{  
  116.     private ReceiverA receiver = new ReceiverA();  
  117.     @Override
  118.     publicvoid execute() {  
  119.         receiver.action();  
  120.     }  
  121.     @Override
  122.     public String toString(){  
  123.         return"ConcreteCommandA ";  
  124.     }  
  125. }  
  126. /** 
  127.  * 具體命令實現,覆蓋預設命令類的execute() 
  128.  */
  129. class ConcreteCommandB extends DefaultCommand{  
  130.     private ReceiverB receiver = new ReceiverB();  
  131.     @Override
  132.     publicvoid execute() {  
  133.         receiver.action();  
  134.     }  
  135.     @Override
  136.     public String toString(){  
  137.         return"ConcreteCommandB ";  
  138.     }  
  139. }  
  140. /** 
  141.  * 巨集命令:使用組合模式和命令模式,批量執行命令  
  142.  */
  143. class MacroCommand implements Command{  
  144.     private List<Command> commands = new ArrayList<Command>();  
  145.     

    相關推薦

    命令模式,資料庫事務,命令撤銷恢復

    命令模式(COMMAND),又稱動作(Action),事務(Transaction),通過將一個請求封裝為一個物件,從而使你可用不同的請求對客戶進行引數化,實現對請求排隊或記錄請求日誌,以及支援可撤銷的操作。命令模式可以將請求傳送者和接收者完全解耦,傳送者與接收者之間沒有

    mysql中如何使用linux命令資料庫進行備份與恢復

    在視覺化介面上很方便對資料庫進行備份和恢復,那麼在如何使用linux命令對資料庫進行備份和恢復呢?首先需要我們退出mysql,然後按如下步驟操作。1、從linux命令列中輸入sudo -s 進入超級管理員模式;2、進入mysql根目錄,即在命令列輸入 cd /var/lib/

    如何採用命令模式實現"撤銷/恢復"

    前言:現在大部分優秀的編輯器都帶有 "撤銷/恢復"功能。這個功能就是相當於傳說中的”後悔藥“,方便大家隨時切換到以前的某一個點。為了尋找“後悔藥”,我們也開始了該功能的探索之旅。本文主要考慮的方法是採用命令模式實現該功能的思路!mwebxcode美圖一、設計模式的一些術語1、

    命令模式的應用之可撤銷/恢復操作的計算器

    深度理解命令模式(1)引數化配置:用不同的命令物件,去引數化配置客戶的請求。(2)可撤銷的操作:  ①補償式(反操作式):如被撤銷的操作是加的功能,那麼反操作就是減的功能。  ②儲存恢復式:把操作前的狀態記錄下來,然後要撤銷操作時就直接恢復回去就可以了。(該種方式會放到備忘錄

    MySQL 資料庫增量備份與恢復資料命令實戰

    1. 備份單個數據庫練習 mysqldump 命令多種引數的使用 1.1 調整 MySQL 客戶端及服務端字符集為建庫建表時預設的 latin1,避免備份時的亂碼問題 [[email protected] ~]# vi /etc/my.cnf [[email protected] ~

    【Redis資料庫命令學習筆記——釋出訂閱、事務、指令碼、連線命令彙總

    本篇基於redis 4.0.11版本,學習釋出訂閱、事務、指令碼、連線的相關命令。 Redis 釋出訂閱(pub/sub)是一種訊息通訊模式:傳送者(pub)傳送訊息,訂閱者(sub)接收訊息。 序

    【程式設計模式】(一) ------ 命令模式 和 “重做” 及 “撤銷

    前言 本文及以後該系列的篇章都是本人對 《遊戲程式設計模式》這本書的閱讀理解,從中對一些原理,用更直白的語言描述出來,並對部分思路或功能進行初步實現。而本文所描述的 命令模式, 相信讀者應該都有了解過或聽說過,如果尚有疑惑的讀者,我希望本文能對你有所幫助。 命令模式是設計模式中的一種,但該系列所指的程式設計模

    beego——事務處理和命令模式

    1.事務處理 ORM 可以簡單的進行事務操作。 o := NewOrm() err := o.Begin() // 事務處理過程 ... ... // 此過程中的所有使用 o Ormer 物件的查詢都在事務處理範圍內 if SomeError { err = o.Rollback() } e

    使用mongoDB必須要知道的備份和恢復資料庫命令

    部分恢復:mongorestore -h 192.168.88.88 -d dris D:MongoDBdataBak88cmlibdris_digital.bson 匯出資料表dris_digital到dris中

    mongoDB中備份和恢復資料庫命令

    部分恢復:mongorestore -h 192.168.88.88 -d dris D:\MongoDB\dataBak\88\cmlib\dris_digital.bson 匯出資料表dris_digital到dris中

    設計模式初探-命令模式(COMMAND),又稱動作(Action),事務(Transaction)

    命令模式(COMMAND),又稱動作(Action),事務(Transaction),通過將一個請求封裝為一個物件,從而使你可用不同的請求對客戶進行引數化,實現對請求排隊或記錄請求日誌,以及支援可撤銷的操作。命令模式可以將請求傳送者和接收者完全解耦,傳送者與接收者之間沒有

    設計模式命令模式

    能夠 ger 不同 exec cor del 需要 content ces 設計模式之命令模式 Feb 24, 2015 命令模式(Command)的定義是:用於將一個請求封裝成一個對象,從而使你可用不同的請求對客戶進行參數化;對請求排隊或者記錄請求日誌,以及執行可撤銷的

    javascript設計模式詳解之命令模式

    這一 clas 例子 別了 logs 操作 book 技術 概念   每種設計模式的出現都是為了彌補語言在某方面的不足,解決特定環境下的問題。思想是相通的。只不過不同的設計語言有其特定的實現。對javascript這種動態語言來說,弱類型的特性,與生俱來的多態性,導致某些設

    設計模式命令模式(Command)摘錄

    single 而是 names 都得 結構 意圖 iterator nbsp 軟件 23種GOF設計模式一般分為三大類:創建型模式、結構型模式、行為模式。創建型模式抽象了實例化過程,它們幫助一個系統獨立於怎樣創建、組合和表示它的那些對象。一個類創建型模式使用繼承改變被實例

    CentOS7 Tools安裝步驟(命令模式安裝)

    編譯工具 .com 共享 cer 需要 顯示 mes 沒有 重新 1、首先啟動CentOS 7,在VMware中點擊上方“VM”,點擊“Install VMware Tools...”(如已安裝則顯示“Reinstall VMware Tools...”)。 2、在命令行輸

    設計模式——命令模式(C++實現)

    clear cto ive pre urn bak std oot style 1 [root@ ~/learn_code/design_pattern/19_order]$ cat order.cpp 2 #include <

    PHP面向對象之命令模式

    rac cte cti mat extends fault registry extend urn 這個模式主要由 命令類、用戶請求數據類、業務邏輯類、命令類工廠類及調用類構成,各個類的作用概括如下: 1、命令類:調用用戶請求數據類和業務邏輯類; 2、用戶請求數據類:獲取用

    [CentOS 7系列]VIM編輯模式命令模式

    用戶 mtime 一、編輯模式按鍵作用i在當前字符前插入I在光標所在行的行首插入a在當前字符後插入A在光標所在行的行尾插入o在當前行的下一行插入新的一行O在當前的上一行插入新的一行二、命令模式命令作用/word向光標之後查找一個字符word,按n向後繼續搜索?word向光標之前查找一個字符word,按

    vi命令-模式轉換

    vi命令-模式轉換1.模式轉換i: 在當前光標所在字符的前面,轉為輸入模式; a:在當前光標所在字符的後面,轉為輸入模式; o:在當前光標所在行的下方,新建一行,並轉為輸入模式; I:在當前光標所在行的行首,轉換為輸入模式 A:在當前光標所在行的行尾,轉換為輸入模式 O:在當前光標所在行的上方,新

    命令模式(三)

    設計模式 命令模式 隊列請求 所謂隊列請求,就是對命令對象進行排隊,組成工作隊列,然後依次取出命令對象來執行。多用多線程或者線程池來進行命令隊列的處理,當然也可以不用多線程,就是一個線程,一個命令一個命令的循環處理,就是慢點。 繼續宏命令的例子,其實在後廚,會收到很多很多的