前言
最近学习微服务的hystrix组件,了解到hystrix使用到了命令模式。我觉得设计模式的学习不能脱离实际,你必须知道什么情况下需要使用到它,该如何去使用,否则就没有学习到精髓,学习的目的还是要使用,将它应用到实际的工作中,让我们的代码更加的简洁易读、更易扩展。
一、命令模式的定义
首先我们来看一下官方是如何定义它的。
命令模式:Encapsulate a request as an object,there by letting you parameterize clients with different requests,queue or log requests,and support undoable operations.
(将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。)
官方的解释看起来有点难以理解,简单来说就是,将客户端请求封装成一个对象,从而把命令的请求和命令执行两个操作分开,实现请求方和执行方的松耦合。
二、命令模式的结构
命令模式包含以下主要角色:
- 抽象命令类(Command)角色:声明执行命令的接口,拥有执行命令的抽象方法 execute()。
- 具体命令角色(Concrete Command)角色:是抽象命令类的具体实现类,它拥有接收者对象,并通过调用接收者的功能来完成命令要执行的操作。
- 实现者/接收者(Receiver)角色:执行命令功能的相关操作,是具体命令对象业务的真正实现者。
- 调用者/请求者(Invoker)角色:是请求的发送者,它通常拥有很多的命令对象,并通过访问命令对象来执行相关请求,它不直接访问接收者。
结构图如下:

我们需要根据实际的业务场景,找出相应的请求者和接收者,然后再进行代码的编写。找到这几个角色是很重要的!
三、命令模式的应用
1.点餐场景模拟
这里借用小傅哥《重学java设计模式》一书中的例子来做讲解。有兴趣的同学也可以看一看这本书,对设计模式的讲解很透彻。
在这张图片中,模拟了客户点餐下单的过程。客户点餐与厨师的烹饪是两个过程,现在我们来找出这个业务场景中的几个命令模式的角色,命令、接收者、请求者。大家应该很快就能找出,命令(客户点菜)、接收者(厨师)、请求者(小二)。
1、首先创建命令接口
public interface Food {
public void execute();
}
客户点单的命令接口,接口需要包含执行命令的方法execute()。
2、实现具体命令接口,客户具体的点菜命令
public class GuangDongFood implements Food {
private Cooker cooker;
public GuangDongFood(Cooker cooker) {
this.cooker = cooker;
}
@Override
public void execute() {
cooker.doCooking();
}
}
这里只实现其中一种,其它的命令实现类似。命令实现需要包含接收者对象Cooker。
3、请求者的实现,即小二
public class XiaoEr {
List<Food> list = new ArrayList<>();
//点单
public void order(Food food) {
list.add(food);
}
//下单
public void placeOrder() {
list.forEach(Food::execute);
}
}
请求者通过命令对象来执行做菜的请求,不直接访问接收者(厨师)。
4、接收者接口,即厨师接口
public interface Cooker {
void doCooking();
}
5、接收者实现,需要实现具体的业务(做菜)
public class GuangDongCooker implements Cooker {
@Override
public void doCooking() {
System.out.println("广东厨师烹饪广东菜..........");
}
}
这里也只给出一种,其它的厨师实现也是类似。
6、测试类
public class CommandTest {
public static void main(String[] args) {
XiaoEr xiaoEr = new XiaoEr();
xiaoEr.order(new GuangDongFood(new GuangDongCooker()));
xiaoEr.order(new HuNanFood(new HuNanCooker()));
xiaoEr.order(new JangNanFood(new JiangNanCooker()));
xiaoEr.placeOrder();
}
}
这样就实现了整个点餐的过程,客户点单与具体的厨师做菜是两个独立的过程。具体的代码在文章最后的链接处。
2.hystrix对命令模式的应用(待更新)
说句实话,我也没搞太明白,只知道HystrixCommand这里使用了命令模式来包装依赖调用逻辑。只有去看hystrix的源码才能搞明白了,目前我是还没有搞清楚,我会继续看的,搞明白了再来补充。如果您理解清楚了,也麻烦您给讲讲,谢谢!
四、源码以及参考地址
源码地址
参考1:小傅哥《重学java设计模式》
参考2:命令模式(详解版)
总结
关于命令模式,我就先说这么多了,主要还是命令模式的应用,一定要在实际的业务中去使用才能真正的掌握它,关于它的优缺点这里就不再说了,用了才能知道,不用说了也没用。我个人也还有些没有弄明白的地方,当我有了新的收获,我会继续更新这篇文章,也请大家给予指导和建议,谢谢!
本文深入解析了命令模式,通过点餐场景模拟阐述了命令模式的结构与角色,包括抽象命令、具体命令、接收者和请求者。此外,探讨了Hystrix如何利用命令模式实现服务容错,虽然作者尚未完全理解,但仍鼓励读者自行研究。文章提供了详细的代码示例和参考资料,帮助读者在实际项目中运用命令模式。
7472

被折叠的 条评论
为什么被折叠?



