Java設(shè)計(jì)模式之命令模式詳細(xì)解析
1、簡(jiǎn)介
1.1、定義
命令模式:將請(qǐng)求封裝成對(duì)象,以便使用不同的請(qǐng)求、隊(duì)列或者日志來參數(shù)化其他對(duì)象。(同時(shí)也支持可撤銷的操作)
1.2、解決的問題
通常在系統(tǒng)設(shè)計(jì)中,行為請(qǐng)求者和行為實(shí)現(xiàn)者是緊耦合的關(guān)系。
而在一些特定的場(chǎng)景下,比如:需要對(duì)行為進(jìn)行記錄、撤銷或重做、事務(wù)等處理時(shí),需要將行為請(qǐng)求者和行為實(shí)現(xiàn)者分離開來,這時(shí)就可以用到命令模式。
1.3、模式結(jié)構(gòu)
- Command:定義命令的接口,聲明執(zhí)行的方法
- ConcreteCommand:命令接口實(shí)現(xiàn)對(duì)象,是“命令接口”的實(shí)現(xiàn);通常會(huì)持有接收者,并調(diào)用接收者的功能來完成命令要執(zhí)行的操作
- Receiver:接收者,真正執(zhí)行命令的對(duì)象。任何類都可能成為一個(gè)接收者,只要它能夠?qū)崿F(xiàn)命令要求實(shí)現(xiàn)的相應(yīng)功能
- Invoker:要求命令對(duì)象執(zhí)行請(qǐng)求,通常會(huì)持有命令對(duì)象,可以持有很多的命令對(duì)象。這個(gè)是客戶端真正觸發(fā)命令并要求命令執(zhí)行相應(yīng)操作的地方,也就是說相當(dāng)于使用命令對(duì)象的入口
- Client:創(chuàng)建具體的命令對(duì)象,并且設(shè)置命令對(duì)象的接收者。注意這個(gè)不是我們常規(guī)意義上的客戶端,而是在組裝命令對(duì)象和接收者,或許,把這個(gè)Client稱為裝配者會(huì)更好理解,因?yàn)檎嬲褂妹畹目蛻舳耸菑腎nvoker來觸發(fā)執(zhí)行
1.4、結(jié)構(gòu)類圖
1.5、運(yùn)作流程
- Client創(chuàng)建一個(gè)ConcreteCommand對(duì)象并指定他的Receiver對(duì)象
- 某個(gè)Invoker對(duì)象存儲(chǔ)該ConcreteCommand對(duì)象
- 該Invoker通過調(diào)用Command對(duì)象的Execute操作來提交一個(gè)請(qǐng)求。若該命令是可撤銷的,ConcreteCommand就在執(zhí)行Execute操作之前存儲(chǔ)當(dāng)前狀態(tài)以用于取消該命令
- ConcreteCommand對(duì)象對(duì)調(diào)用它的Receiver的一些操作以執(zhí)行該請(qǐng)求
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: 請(qǐng)求類 --- Receiver * @author: JiangBeiPing * @create: 2021-07-23 11:16 * @Version: 1.0 **/ public class Stock { private String name = "庫存一號(hào)"; // 數(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: 測(cè)試 --- 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è)計(jì)一個(gè)組合命令
缺點(diǎn)
Command的子類過多(如果有過多的命令,就會(huì)有過多的Command子類)
使用場(chǎng)景
隊(duì)列請(qǐng)求日志請(qǐng)求系統(tǒng)需要將一組操作組合在一起,即支持宏命令
到此這篇關(guān)于Java設(shè)計(jì)模式之命令模式詳細(xì)解析的文章就介紹到這了,更多相關(guān)Java命令模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Boot基礎(chǔ)學(xué)習(xí)之Mybatis操作中使用Redis做緩存詳解
這篇文章主要給大家介紹了關(guān)于Spring Boot基礎(chǔ)學(xué)習(xí)之Mybatis操作中使用Redis做緩存的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用spring boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧2018-11-11MybatisPlus使用Mybatis的XML的動(dòng)態(tài)SQL的功能實(shí)現(xiàn)多表查詢
本文主要介紹了MybatisPlus使用Mybatis的XML的動(dòng)態(tài)SQL的功能實(shí)現(xiàn)多表查詢,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-11-11java 方法重寫與權(quán)限修飾符以及多態(tài)和抽象類詳解概念和用法
重寫是子類對(duì)父類的允許訪問的方法的實(shí)現(xiàn)過程進(jìn)行重新編寫, 返回值和形參都不能改變。即外殼不變,核心重寫,權(quán)限修飾符用于控制被修飾變量、方法、類的可見范圍,說明了面向?qū)ο蟮姆庋b性,所以我們要適用他們盡可能的讓權(quán)限降到最低,從而安全性提高2021-10-10SpringBoot同一接口多個(gè)實(shí)現(xiàn)類配置的實(shí)例詳解
這篇文章主要介紹了SpringBoot同一接口多個(gè)實(shí)現(xiàn)類配置的實(shí)例詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11eclipse中沒有SERVER的解決辦法(超詳細(xì))
使用eclipse進(jìn)行tomcat配置時(shí),經(jīng)常會(huì)發(fā)現(xiàn)一個(gè)重要的問題就是打開eclipse之后沒有了server選項(xiàng),所以本給大家詳細(xì)介紹了eclipse中沒有SERVER的解決辦法,文中有詳細(xì)的圖文講解,需要的朋友可以參考下2023-12-12java final 和instanceof 關(guān)鍵字的區(qū)別
這篇文章介紹了java final 和instanceof 關(guān)鍵字的區(qū)別,有需要的朋友可以參考一下2013-09-09java高級(jí)應(yīng)用:線程池的全面講解(干貨)
這篇文章主要介紹了java高級(jí)應(yīng)用:線程池的全面講解(干貨),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-02-02