type
status
date
slug
summary
tags
category
icon
password

一、定义

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

二、示例:

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

传统编码

通过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));   } }
测试: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();   } }

命令模式设计

定义做菜的接口,由各个厨师具体实现
package com.qf.design.behavior.command.design.cook; public interface ICook {    /**     * 做菜     */    void cook(); }
四川厨师
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("四川厨师,烹饪川菜,中国最有特⾊的菜系,也是⺠间最⼤菜系。");   } }
⼭东厨师
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("⼭东厨师,烹饪鲁菜,宫廷最⼤菜系,以孔府⻛味为⻰头");   } }
江苏厨师
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("江苏厨师,烹饪苏菜,宫廷第⼆⼤菜系,古今国宴上最受⼈欢迎的菜系");   } }
⼴东厨师
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("⼴东厨师,烹饪鲁菜,宫廷最⼤菜系,以孔府⻛味为⻰头");   } }
定义每个菜肴的接口,由各个菜肴具体实现
package com.qf.design.behavior.command.design.cusine; public interface ICusine {    void cook(); }
四川菜
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();   } }
山东菜
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();   } }
江苏菜
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();   } }
粤菜
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();   } }
店小二负责接受客人的点单信息,转发至厨师们去实现
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();   } }
测试: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();   } }

UML关系图

notion image
总结: 从以上的内容和例⼦可以感受到,命令模式的使⽤场景需要分为三个⽐较⼤的块;
命令 、 实现 、调⽤者
,⽽这三块内容的拆分也是选择适合场景的关键因素,经过这样的拆分可以让逻辑具备单⼀职责的性质,便于扩展。
通过这样的实现⽅式与if语句相⽐,降低了耦合性也⽅便其他的命令和实现的扩展。但同时这样的设计模式也带来了⼀点问题,就是在各种命令与实现的组合下,会扩展出很多的实现类,需要进⾏管理。
 
JAVA【设计模式】责任链模式JAVA【设计模式】中介模式