• 小侃设计模式(十五)-命令模式


    1.概述

    命令模式(Command Pattern)是将一个请求封装为一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。它是行为型模式的一种,能够有效降低系统间的耦合性。本文将详述命令模式的设计原理及使用。

    2.原理及使用

    2.1 原理

    命令模式是对命令的一个封装,它将发出命令的责任和执行命令的责任进行分开,委派给不同的对象。命令模式的类图如下所示:
    在这里插入图片描述

    命令模式涉及到五个角色,它们分别是:

    • 客户端角色(Client):创建一个具体命令对象并确定其接收者;
    • 命令角色(Command):声明一个所有命令类实现的抽象接口;
    • 具体命令角色(ConcreteCommand):定义一个接收者和其实现的一个弱耦合,它实现命令角色(Command)中的execute()方法,execut()方法调用具体的接收者Receiver中的方法进行实现;
    • 请求者角色(Invoker):负责调用命令对象执行请求,相关的方法叫做行动方法;
    • 接收者角色(Receiver):请求的具体实现对象,任何一个类都可以成为接收者,实施和执行请求的方法叫做行动方法。

    2.2 案例

    饭店里有做各种不同菜系的厨子,有湘菜厨子、徽菜厨子、川菜厨子、粤菜厨子等,客人会找服务员进行点菜,服务员会根据客人点的不同的菜找不同的厨师加工。

    在上述案例中,客户端角色就相当于客户,发出请求,服务员相当于请求者角色,请求厨子去按用户要求做菜,接收者角色就是具体的厨师,具体类图如下:

    在这里插入图片描述

    代码实现如下:

    //烹饪命令角色
    public interface Cooking {
    
        void execute();
    
    }
    
    //徽菜做法
    public class HuiCooking implements Cooking{
    
        private HuiCooker cooker;
    
        public HuiCooking(HuiCooker cooker) {
            this.cooker = cooker;
        }
    
        @Override
        public void execute() {
            cooker.act();
        }
    }
    
    //粤菜做法
    public class YueCooking implements Cooking {
    
        private YueCooker cooker;
    
        public YueCooking(YueCooker cooker) {
            this.cooker = cooker;
        }
    
        @Override
        public void execute() {
            cooker.act();
        }
    
    }
    
    //粤菜厨子角色
    public class YueCooker {
    
        public void act() {
            System.out.println("粤菜厨子,做的一手好粤菜,正在烹饪粤菜");
        }
    
    }
    
    //徽菜厨子角色
    public class HuiCooker  {
    
        public void act() {
            System.out.println("徽菜厨子,做的一手好徽菜,正在烹饪徽菜");
        }
    
    }
    
    //服务员,请求者角色
    public class Waiter {
    
        private List<Cooking> orders = new ArrayList<>();
    
        public void setOrders(Cooking cooking) {
            orders.add(cooking);
        }
    
        //下单
        public void placeOrder() {
            for (Cooking order : orders) {
                order.execute();
            }
            orders.clear();
        }
    
    }
    
    //测试类
    public class Client {
    
        public static void main(String[] args) {
            YueCooker yueCooker = new YueCooker();
            HuiCooker huiCooker = new HuiCooker();
    
            YueCooking yueCooking = new YueCooking(yueCooker);
            HuiCooking huiCooking = new HuiCooking(huiCooker);
    
            Waiter waiter = new Waiter();
            //客户点个粤菜
            waiter.setOrders(yueCooking);
            //客户点个徽菜
            waiter.setOrders(huiCooking);
    
            //服务员下单
            waiter.placeOrder();
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97

    测试结果如下:

    在这里插入图片描述

    2.3 命令模式的优缺点

    2.3.1 优点

    1.松耦合:命令模式将命令发起者与接收者对象进行解耦,发起者不知道接收者的具体对象,
    2.扩展性更强:若增加新的命令对象,只需扩展命令接口,然后将具体命令对象装配即可;
    3.控制更灵活:命令模式可以将请求封装,动态进行参数化、队列化等,使系统更加灵活。

    2.3.2 缺点

    1.增加系统的复杂度:可能导致某些系统有较多的命令类,增加系统复杂度;
    2.请求者和接收者之间仍然存在耦合,若接收者变更,请求者也要进行代码变更。

    2.4 注意事项和细节

    命令模式的经典使用场景:界面的每一个按钮都是一个命令、模拟CMD(DOS命令)、订单的撤销/恢复、触发-反馈机制等。

    3.小结

    1.命令模式最大的优点在于将请求与具体的实现对象进行解耦,使得请求命令易于扩展;
    2.它的优点也是它的缺点,当系统中命令过多时,容易造成类爆炸,所以要根据场景进行模式识别与组合。

    4.参考文献

    1.《设计模式之禅》-秦小波著
    2.《大话设计模式》-程杰著
    3.https://www.cnblogs.com/betterboyz/p/9377991.html

  • 相关阅读:
    无线智能振弦采集系统(NLM5或6多通道无线采集采发仪)
    Linux ubuntu磁盘扩容
    美女程序员:仅有30天,该怎么准备?
    flink cdc原理与使用
    如何使用 JavaScript/jQuery 为网站创建暗/亮模式?
    融合鲸鱼算法的混合灰狼优化算法
    实时云渲染技术,元宇宙应用的核心之一
    Java零基础教学都讲什么内容?
    LwIP笔记02:
    原型和原型链
  • 原文地址:https://blog.csdn.net/qq_33479841/article/details/127970291