Java設(shè)計模式之命令模式詳細(xì)解析
1、簡介
1.1、定義
命令模式:將請求封裝成對象,以便使用不同的請求、隊列或者日志來參數(shù)化其他對象。(同時也支持可撤銷的操作)
1.2、解決的問題
通常在系統(tǒng)設(shè)計中,行為請求者和行為實現(xiàn)者是緊耦合的關(guān)系。
而在一些特定的場景下,比如:需要對行為進(jìn)行記錄、撤銷或重做、事務(wù)等處理時,需要將行為請求者和行為實現(xiàn)者分離開來,這時就可以用到命令模式。
1.3、模式結(jié)構(gòu)
- Command:定義命令的接口,聲明執(zhí)行的方法
- ConcreteCommand:命令接口實現(xiàn)對象,是“命令接口”的實現(xiàn);通常會持有接收者,并調(diào)用接收者的功能來完成命令要執(zhí)行的操作
- Receiver:接收者,真正執(zhí)行命令的對象。任何類都可能成為一個接收者,只要它能夠?qū)崿F(xiàn)命令要求實現(xiàn)的相應(yīng)功能
- Invoker:要求命令對象執(zhí)行請求,通常會持有命令對象,可以持有很多的命令對象。這個是客戶端真正觸發(fā)命令并要求命令執(zhí)行相應(yīng)操作的地方,也就是說相當(dāng)于使用命令對象的入口
- Client:創(chuàng)建具體的命令對象,并且設(shè)置命令對象的接收者。注意這個不是我們常規(guī)意義上的客戶端,而是在組裝命令對象和接收者,或許,把這個Client稱為裝配者會更好理解,因為真正使用命令的客戶端是從Invoker來觸發(fā)執(zhí)行
1.4、結(jié)構(gòu)類圖
1.5、運(yùn)作流程
- Client創(chuàng)建一個ConcreteCommand對象并指定他的Receiver對象
- 某個Invoker對象存儲該ConcreteCommand對象
- 該Invoker通過調(diào)用Command對象的Execute操作來提交一個請求。若該命令是可撤銷的,ConcreteCommand就在執(zhí)行Execute操作之前存儲當(dāng)前狀態(tài)以用于取消該命令
- ConcreteCommand對象對調(diào)用它的Receiver的一些操作以執(zhí)行該請求
2、示例Demo
2.1、Command
package com.jbp.designpattern.command; /** * @ClassName: Order * @description: 命令接口 --- Command * @author: JiangBeiPing * @create: 2021-07-23 11:15 * @Version: 1.0 **/ public interface Order { void execute(); }
2.2、ConcreteCommand
package com.jbp.designpattern.command; /** * @ClassName: BuyStock * @description: 加庫存 --- ConcreteCommmand * @author: JiangBeiPing * @create: 2021-07-23 11:39 * @Version: 1.0 **/ public class BuyStock implements Order{ private Stock stock; public BuyStock(Stock stock) { this.stock = stock; } @Override public void execute() { stock.buy(); } }
package com.jbp.designpattern.command; /** * @ClassName: SellStock * @description: 清庫存 --- ConcreteCommmand * @author: JiangBeiPing * @create: 2021-07-23 11:41 * @Version: 1.0 **/ public class SellStock implements Order{ private Stock stock; public SellStock(Stock stock) { this.stock = stock; } @Override public void execute() { stock.sell(); } }
2.3、Receiver
package com.jbp.designpattern.command; /** * @ClassName: Stock * @description: 請求類 --- Receiver * @author: JiangBeiPing * @create: 2021-07-23 11:16 * @Version: 1.0 **/ public class Stock { private String name = "庫存一號"; // 數(shù)量 private int quantity = 10; public void buy(){ System.out.println("名字:" + name + ",數(shù)量:" + quantity); } public void sell(){ System.out.println("名字:" + name + ",數(shù)量:" + quantity); } }
2.4、Invoker
package com.jbp.designpattern.command; import java.util.ArrayList; import java.util.List; /** * @ClassName: Broker * @description: 命令調(diào)用類 --- invoker * @author: JiangBeiPing * @create: 2021-07-23 11:43 * @Version: 1.0 **/ public class Broker { private List<Order> orderList = new ArrayList<>(); // 加庫存 public void takeOrder(Order order){ orderList.add(order); } // 清庫存 public void placeOrders(){ for (Order order : orderList) { order.execute(); } orderList.clear(); } }
2.5、Client
package com.jbp.designpattern.command; /** * @ClassName: test * @description: 測試 --- Client * @author: JiangBeiPing * @create: 2021-07-23 11:50 * @Version: 1.0 **/ public class test { public static void main(String[] args) { Stock stock = new Stock(); BuyStock buyStock = new BuyStock(stock); SellStock sellStock = new SellStock(stock); Broker broker = new Broker(); broker.takeOrder(buyStock); broker.takeOrder(sellStock); broker.placeOrders(); } }
3、優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
類間解耦:調(diào)用者角色與接收者角色之間沒有任何依賴關(guān)系可擴(kuò)展性:Command的子類具備高擴(kuò)展性可以比較容易地設(shè)計一個組合命令
缺點(diǎn)
Command的子類過多(如果有過多的命令,就會有過多的Command子類)
使用場景
隊列請求日志請求系統(tǒng)需要將一組操作組合在一起,即支持宏命令
到此這篇關(guān)于Java設(shè)計模式之命令模式詳細(xì)解析的文章就介紹到這了,更多相關(guān)Java命令模式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Boot基礎(chǔ)學(xué)習(xí)之Mybatis操作中使用Redis做緩存詳解
這篇文章主要給大家介紹了關(guān)于Spring Boot基礎(chǔ)學(xué)習(xí)之Mybatis操作中使用Redis做緩存的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用spring boot具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧2018-11-11MybatisPlus使用Mybatis的XML的動態(tài)SQL的功能實現(xiàn)多表查詢
本文主要介紹了MybatisPlus使用Mybatis的XML的動態(tài)SQL的功能實現(xiàn)多表查詢,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-11-11java 方法重寫與權(quán)限修飾符以及多態(tài)和抽象類詳解概念和用法
重寫是子類對父類的允許訪問的方法的實現(xiàn)過程進(jìn)行重新編寫, 返回值和形參都不能改變。即外殼不變,核心重寫,權(quán)限修飾符用于控制被修飾變量、方法、類的可見范圍,說明了面向?qū)ο蟮姆庋b性,所以我們要適用他們盡可能的讓權(quán)限降到最低,從而安全性提高2021-10-10SpringBoot同一接口多個實現(xiàn)類配置的實例詳解
這篇文章主要介紹了SpringBoot同一接口多個實現(xiàn)類配置的實例詳解,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11eclipse中沒有SERVER的解決辦法(超詳細(xì))
使用eclipse進(jìn)行tomcat配置時,經(jīng)常會發(fā)現(xiàn)一個重要的問題就是打開eclipse之后沒有了server選項,所以本給大家詳細(xì)介紹了eclipse中沒有SERVER的解決辦法,文中有詳細(xì)的圖文講解,需要的朋友可以參考下2023-12-12java final 和instanceof 關(guān)鍵字的區(qū)別
這篇文章介紹了java final 和instanceof 關(guān)鍵字的區(qū)別,有需要的朋友可以參考一下2013-09-09