type
status
date
slug
summary
tags
category
icon
password
一、定义

命令模式:将一个
请求封装为一个对象
,使发出请求的
责任和执行请求过程分隔
开。这样两者之间通过命令对象进行沟通,便于将命令对象进行储存、传递,增强。
二、示例:
模拟场景:
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)); } }
测试:
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关系图

总结:
从以上的内容和例⼦可以感受到,命令模式的使⽤场景需要分为三个⽐较⼤的块;
命令 、 实现 、调⽤者
,⽽这三块内容的拆分也是选择适合场景的关键因素,经过这样的拆分可以让逻辑具备单⼀职责的性质,便于扩展。
通过这样的实现⽅式与if语句相⽐,降低了耦合性也⽅便其他的命令和实现的扩展。但同时这样的设计模式也带来了⼀点问题,就是在各种命令与实现的组合下,会扩展出很多的实现类,需要进⾏管理。
- 作者:程序员小舟
- 链接:https://codezhou.top/article/JAVA%E3%80%90%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%91%E5%91%BD%E4%BB%A4%E6%A8%A1%E5%BC%8F
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章