带你入门设计模式-命令模式

本文深入解析了命令模式,通过点餐场景模拟阐述了命令模式的结构与角色,包括抽象命令、具体命令、接收者和请求者。此外,探讨了Hystrix如何利用命令模式实现服务容错,虽然作者尚未完全理解,但仍鼓励读者自行研究。文章提供了详细的代码示例和参考资料,帮助读者在实际项目中运用命令模式。


前言

最近学习微服务的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.
(将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。)

官方的解释看起来有点难以理解,简单来说就是,将客户端请求封装成一个对象,从而把命令的请求和命令执行两个操作分开,实现请求方和执行方的松耦合。

二、命令模式的结构

命令模式包含以下主要角色:

  1. 抽象命令类(Command)角色:声明执行命令的接口,拥有执行命令的抽象方法 execute()。
  2. 具体命令角色(Concrete Command)角色:是抽象命令类的具体实现类,它拥有接收者对象,并通过调用接收者的功能来完成命令要执行的操作。
  3. 实现者/接收者(Receiver)角色:执行命令功能的相关操作,是具体命令对象业务的真正实现者。
  4. 调用者/请求者(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:命令模式(详解版)

总结

关于命令模式,我就先说这么多了,主要还是命令模式的应用,一定要在实际的业务中去使用才能真正的掌握它,关于它的优缺点这里就不再说了,用了才能知道,不用说了也没用。我个人也还有些没有弄明白的地方,当我有了新的收获,我会继续更新这篇文章,也请大家给予指导和建议,谢谢!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值