Java设计模式之命令模式详细解析
1、简介
1.1、定义
命令模式:将请求封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。(同时也支持可撤销的操作)
1.2、解决的问题
通常在系统设计中,行为请求者和行为实现者是紧耦合的关系。
而在一些特定的场景下,比如:需要对行为进行记录、撤销或重做、事务等处理时,需要将行为请求者和行为实现者分离开来,这时就可以用到命令模式。
1.3、模式结构
- Command:定义命令的接口,声明执行的方法
- ConcreteCommand:命令接口实现对象,是“命令接口”的实现;通常会持有接收者,并调用接收者的功能来完成命令要执行的操作
- Receiver:接收者,真正执行命令的对象。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能
- Invoker:要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口
- Client:创建具体的命令对象,并且设置命令对象的接收者。注意这个不是我们常规意义上的客户端,而是在组装命令对象和接收者,或许,把这个Client称为装配者会更好理解,因为真正使用命令的客户端是从Invoker来触发执行
1.4、结构类图
1.5、运作流程
- Client创建一个ConcreteCommand对象并指定他的Receiver对象
- 某个Invoker对象存储该ConcreteCommand对象
- 该Invoker通过调用Command对象的Execute操作来提交一个请求。若该命令是可撤销的,ConcreteCommand就在执行Execute操作之前存储当前状态以用于取消该命令
- ConcreteCommand对象对调用它的Receiver的一些操作以执行该请求
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 = "库存一号"; // 数量 private int quantity = 10; public void buy(){ System.out.println("名字:" + name + ",数量:" + quantity); } public void sell(){ System.out.println("名字:" + name + ",数量:" + quantity); } }
2.4、Invoker
package com.jbp.designpattern.command; import java.util.ArrayList; import java.util.List; /** * @ClassName: Broker * @description: 命令调用类 --- 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、优缺点
优点
类间解耦:调用者角色与接收者角色之间没有任何依赖关系可扩展性:Command的子类具备高扩展性可以比较容易地设计一个组合命令
缺点
Command的子类过多(如果有过多的命令,就会有过多的Command子类)
使用场景
队列请求日志请求系统需要将一组操作组合在一起,即支持宏命令
到此这篇关于Java设计模式之命令模式详细解析的文章就介绍到这了,更多相关Java命令模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
详解Spring Boot中使用@Scheduled创建定时任务
本篇文章中主要介绍了Spring Boot中使用@Scheduled创建定时任务,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。2017-03-03Springboot获取jar包中resources资源目录下的文件
今天在项目中遇到一个业务场景,需要用到resources资源目录下的文件,本文主要介绍了Springboot获取jar包中resources资源目录下的文件,感兴趣的可以了解一下2023-12-12Spring Boot日志SLF4J和Logback示例详解
这篇文章主要介绍了Spring Boot日志SLF4J和Logback详解,Logback相比于Log4j,性能提高了10倍以上的性能,占用的内存也变小了,并且文档十分详细,推荐使用Slf4j+Logback,需要的朋友可以参考下2023-07-07Feign实现多文件上传,Open Feign多文件上传问题及解决
这篇文章主要介绍了Feign实现多文件上传,Open Feign多文件上传问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-11-11
最新评论