• JAVA【设计模式】命令模式


    一、定义

    在这里插入图片描述
    命令模式:将一个请求封装为一个对象,使发出请求的责任和执行请求过程分隔开。这样两者之间通过命令对象进行沟通,便于将命令对象进行储存、传递,增强。

    二、示例:

    模拟场景:
    1、餐厅点菜,菜品分类为:⼭东(鲁菜)、四川(川菜)、江苏(苏菜)、⼴东(粤菜)、福建(闽菜)、浙江(浙菜)、湖南(湘菜)等,每个菜肴都有对应的厨师炒出来,例如湖南厨师炒湘菜,广东厨师炒粤菜。客户向店小二提出炒什么菜肴的请求,就会有对应的厨师去处理。
    在这里插入图片描述

    传统编码

    通过if实现,客气请求不同的类型,炒出什么样的菜。例如类型增多,代码会变的很臃肿

    package com.qf.design.behavior.command.tradition;
    
    
    import com.alibaba.fastjson.JSON;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.util.HashMap;
    import java.util.Map;
    
    public class XiaoER {
        private Logger logger= LoggerFactory.getLogger(XiaoER.class);
    
        private Map<Integer,String> map=new HashMap<>();
    
        public void order(int cusine){
            //传统的编码方式所有的情况都在一个方法下面
            if (cusine==1){
                map.put(1, "⼴东厨师,烹饪鲁菜,宫廷最⼤菜系,以孔府⻛味为⻰头");
            }
    
            if (cusine==2){
                map.put(2, "江苏厨师,烹饪苏菜,宫廷第⼆⼤菜系,古今国宴上最受⼈欢迎的菜系");
            }
    
            if (cusine==3){
                map.put(3, "⼭东厨师,烹饪鲁菜,宫廷最⼤菜系,以孔府⻛味为⻰头");
            }
    
            if (cusine==4){
                map.put(4, "四川厨师,烹饪川菜,中国最有特⾊的菜系,也是⺠间最⼤菜系。");
            }
        }
    
        public void placeOrder(){
            logger.info("菜单{}", JSON.toJSONString(map));
        }
    }
    
    
    • 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

    测试:ApiTest

    package com.qf.design.behavior.command.tradition;
    
    public class ApiTest {
        public static void main(String[] args) {
            XiaoER xiaoER=new XiaoER();
            xiaoER.order(1);
            xiaoER.order(2);
            xiaoER.order(3);
            xiaoER.order(4);
            xiaoER.placeOrder();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    命令模式设计

    定义做菜的接口,由各个厨师具体实现

    package com.qf.design.behavior.command.design.cook;
    
    public interface ICook {
    
        /**
         * 做菜
         */
        void cook();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    四川厨师

    package com.qf.design.behavior.command.design.cook.impl;
    
    import com.qf.design.behavior.command.design.cook.ICook;
    import com.qf.design.behavior.command.tradition.XiaoER;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class SiChuangCookImpl implements ICook {
    
        private Logger logger= LoggerFactory.getLogger(XiaoER.class);
        @Override
        public void cook() {
            logger.info("四川厨师,烹饪川菜,中国最有特⾊的菜系,也是⺠间最⼤菜系。");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    ⼭东厨师

    package com.qf.design.behavior.command.design.cook.impl;
    
    import com.qf.design.behavior.command.design.cook.ICook;
    import com.qf.design.behavior.command.tradition.XiaoER;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class ShangDongCookImpl implements ICook {
    
        private Logger logger= LoggerFactory.getLogger(XiaoER.class);
        @Override
        public void cook() {
            logger.info("⼭东厨师,烹饪鲁菜,宫廷最⼤菜系,以孔府⻛味为⻰头");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    江苏厨师

    package com.qf.design.behavior.command.design.cook.impl;
    
    import com.qf.design.behavior.command.design.cook.ICook;
    import com.qf.design.behavior.command.tradition.XiaoER;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class JiangSuCookImpl implements ICook {
    
        private Logger logger= LoggerFactory.getLogger(XiaoER.class);
        @Override
        public void cook() {
            logger.info("江苏厨师,烹饪苏菜,宫廷第⼆⼤菜系,古今国宴上最受⼈欢迎的菜系");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    ⼴东厨师

    package com.qf.design.behavior.command.design.cook.impl;
    
    import com.qf.design.behavior.command.design.cook.ICook;
    import com.qf.design.behavior.command.tradition.XiaoER;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class GuangDongCookImpl implements ICook {
    
        private Logger logger= LoggerFactory.getLogger(XiaoER.class);
        @Override
        public void cook() {
            logger.info("⼴东厨师,烹饪鲁菜,宫廷最⼤菜系,以孔府⻛味为⻰头");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    定义每个菜肴的接口,由各个菜肴具体实现

    package com.qf.design.behavior.command.design.cusine;
    
    public interface ICusine {
        void cook();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    四川菜

    package com.qf.design.behavior.command.design.cusine.impl;
    
    import com.qf.design.behavior.command.design.cook.ICook;
    import com.qf.design.behavior.command.design.cusine.ICusine;
    
    public class SiChuangCusineImpl implements ICusine {
        private ICook cook;
    
        public SiChuangCusineImpl(ICook cook){
            this.cook=cook;
        }
        @Override
        public void cook() {
            cook.cook();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    山东菜

    package com.qf.design.behavior.command.design.cusine.impl;
    
    import com.qf.design.behavior.command.design.cook.ICook;
    import com.qf.design.behavior.command.design.cusine.ICusine;
    
    public class ShangDongCusineImpl implements ICusine {
        private ICook cook;
    
        public ShangDongCusineImpl(ICook cook){
            this.cook=cook;
        }
        @Override
        public void cook() {
            cook.cook();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    江苏菜

    package com.qf.design.behavior.command.design.cusine.impl;
    
    import com.qf.design.behavior.command.design.cook.ICook;
    import com.qf.design.behavior.command.design.cusine.ICusine;
    
    public class JiangSuCusineImpl implements ICusine {
        private ICook cook;
    
        public JiangSuCusineImpl(ICook cook){
            this.cook=cook;
        }
        @Override
        public void cook() {
            cook.cook();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    粤菜

    package com.qf.design.behavior.command.design.cusine.impl;
    
    import com.qf.design.behavior.command.design.cook.ICook;
    import com.qf.design.behavior.command.design.cusine.ICusine;
    
    public class GuangdongCusineImpl implements ICusine {
        private ICook cook;
    
        public GuangdongCusineImpl(ICook cook){
            this.cook=cook;
        }
        @Override
        public void cook() {
            cook.cook();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    店小二负责接受客人的点单信息,转发至厨师们去实现

    package com.qf.design.behavior.command.design;
    
    import com.qf.design.behavior.command.design.cusine.ICusine;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Xiaoer {
        private List<ICusine> cusineList=new ArrayList<>();
    
        public void order(ICusine cusine){
            cusineList.add(cusine);
        }
    
        public synchronized void placeOrder(){
            for (ICusine iCusine : cusineList) {
                iCusine.cook();
            }
    
            cusineList.clear();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    测试:ApiTest

    package com.qf.design.behavior.command.design;
    
    import com.qf.design.behavior.command.design.cook.ICook;
    import com.qf.design.behavior.command.design.cook.impl.GuangDongCookImpl;
    import com.qf.design.behavior.command.design.cook.impl.JiangSuCookImpl;
    import com.qf.design.behavior.command.design.cook.impl.ShangDongCookImpl;
    import com.qf.design.behavior.command.design.cook.impl.SiChuangCookImpl;
    import com.qf.design.behavior.command.design.cusine.ICusine;
    import com.qf.design.behavior.command.design.cusine.impl.GuangdongCusineImpl;
    import com.qf.design.behavior.command.design.cusine.impl.JiangSuCusineImpl;
    import com.qf.design.behavior.command.design.cusine.impl.ShangDongCusineImpl;
    import com.qf.design.behavior.command.design.cusine.impl.SiChuangCusineImpl;
    
    public class ApiTest {
        public static void main(String[] args) {
            ICook siChuangCook = new SiChuangCookImpl();
            ICook JiangSuCookCook = new JiangSuCookImpl();
            ICook ShangDongCookCook = new ShangDongCookImpl();
            ICook GuangDongCook = new GuangDongCookImpl();
    
            ICusine siChuangCusine = new SiChuangCusineImpl(siChuangCook);
            ICusine jiangSuCusine = new JiangSuCusineImpl(JiangSuCookCook);
            ICusine guangdongCusine = new GuangdongCusineImpl(GuangDongCook);
            ICusine shangDongCusine = new ShangDongCusineImpl(ShangDongCookCook);
    
            Xiaoer xiaoer = new Xiaoer();
            xiaoer.order(siChuangCusine);
            xiaoer.order(jiangSuCusine);
            xiaoer.order(guangdongCusine);
            xiaoer.order(shangDongCusine);
    
            xiaoer.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

    UML关系图

    在这里插入图片描述
    总结:
    从以上的内容和例⼦可以感受到,命令模式的使⽤场景需要分为三个⽐较⼤的块; 命令 、 实现 、调⽤者 ,⽽这三块内容的拆分也是选择适合场景的关键因素,经过这样的拆分可以让逻辑具备单⼀职责的性质,便于扩展。

    通过这样的实现⽅式与if语句相⽐,降低了耦合性也⽅便其他的命令和实现的扩展。但同时这样的设计模式也带来了⼀点问题,就是在各种命令与实现的组合下,会扩展出很多的实现类,需要进⾏管理。

  • 相关阅读:
    机器学习 - 决策树:技术全解与案例实战
    扎心了,Java面试不准备真的只有被怼的份儿了
    在 React项目中应用TypeScript
    Canvas相关概念集合
    HAProxy的详解和使用
    vcenter跨版本升级
    Matlab论文插图绘制模板第119期—分组气泡图
    新授粉方式的花授粉算法-附代码
    【ARMv9 DSU-120 系列 2. -- DSU-120 Cluster 中组件详细介绍】
    【Oracle】使用 SQL Developer 连接 Oracle 数据库
  • 原文地址:https://blog.csdn.net/cativen/article/details/126262987