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)缺點
優(yōu)點
類間解耦:調(diào)用者角色與接收者角色之間沒有任何依賴關(guān)系可擴(kuò)展性:Command的子類具備高擴(kuò)展性可以比較容易地設(shè)計一個組合命令
缺點
Command的子類過多(如果有過多的命令,就會有過多的Command子類)
使用場景
隊列請求日志請求系統(tǒng)需要將一組操作組合在一起,即支持宏命令
到此這篇關(guān)于Java設(shè)計模式之命令模式詳細(xì)解析的文章就介紹到這了,更多相關(guān)Java命令模式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決spring-boot-maven-plugin報紅的問題
這篇文章主要給大家介紹一下如何解決spring-boot-maven-plugin報紅的問題,文中通過圖文講解的非常詳細(xì),具有一定的參考價值,需要的朋友可以參考下2023-08-08
Springboot 自定義線程池的參數(shù)配置最優(yōu)小結(jié)
在SpringBoot中配置自定義線程池時,參數(shù)的設(shè)置需要根據(jù)具體的應(yīng)用場景、系統(tǒng)資源和業(yè)務(wù)需求來調(diào)整,本文就來詳細(xì)的介紹一下,感興趣的可以了解一下2025-10-10
Java 格式化輸出String.format() 示例解析
String.format() 是Java中非常強(qiáng)大的工具,掌握它可以讓你在處理字符串輸出時事半功倍,本文給大家介紹Java格式化輸出String.format()的相關(guān)操作,感興趣的朋友跟隨小編一起看看吧2025-12-12
Java調(diào)用Deepseek實現(xiàn)項目代碼審查
這篇文章主要為大家詳細(xì)介紹了Java如何調(diào)用Deepseek實現(xiàn)項目代碼審查功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-02-02

