命令模式就是将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。

一般命令模式由四类组成:

  1. 抽象命令类(Command)角色:声明执行命令的接口,拥有执行命令的抽象方法 execute()。
  2. 具体命令角色(Concrete Command)角色:是抽象命令类的具体实现类,它拥有接收者对象,并通过调用接收者的功能来完成命令要执行的操作。
  3. 实现者/接收者(Receiver)角色:执行命令功能的相关操作,是具体命令对象业务的真正实现者。
  4. 调用者/请求者(Invoker)角色:是请求的发送者,它通常拥有很多的命令对象,并通过访问命令对象来执行相关请求,它不直接访问接收者。

简单的可以理解为下订单,比如我在茶百道点了一杯杨枝甘露,在一点点点了一杯椰果奶茶,又在书亦烧仙草点了一杯烧仙草,如果我一个个的去买就会很麻烦,但是如果我在美团下单,他们制作好了,让跑腿小哥取回来,就会方便很多了,也把我们和几个店铺进行了解耦,并且再下单之前,还可以很方便的取消订单。

=========================================================================

那么我们来实现一下上面的例子:

首先我们定义抽象命令类角色:也就是奶茶店的角色,奶茶店负责实现做奶茶的方法:

package BehavioralPatterns.CommandPattern;/*** @author Zeyu Wan* @version 1.0.0* @ClassName TeaShop.java* @Description 奶茶店接口* @createTime 2022年03月16日 14:46:00*/
public interface TeaShop {/*** 做奶茶*/public void makeTea();
}

然后我们定义三个具体的奶茶店,来实现奶茶店的接口,店铺可以接受订单做奶茶:

茶百道:

package BehavioralPatterns.CommandPattern.shop;import BehavioralPatterns.CommandPattern.Drink;
import BehavioralPatterns.CommandPattern.TeaShop;/*** @author Zeyu Wan* @version 1.0.0* @ClassName ChaBaiDao.java* @Description 茶百道类* @createTime 2022年03月16日 14:56:00*/
public class ChaBaiDao implements TeaShop {private Drink drink;public ChaBaiDao(Drink drink){this.drink = drink;}@Overridepublic void makeTea() {drink.drink();}
}

书亦:

package BehavioralPatterns.CommandPattern.shop;import BehavioralPatterns.CommandPattern.Drink;
import BehavioralPatterns.CommandPattern.TeaShop;/*** @author Zeyu Wan* @version 1.0.0* @ClassName ShuYi.java* @Description 书亦烧仙草类* @createTime 2022年03月16日 14:54:00*/
public class ShuYi implements TeaShop {private Drink drink;public ShuYi(Drink drink){this.drink = drink;}@Overridepublic void makeTea() {drink.drink();}
}

一点点:

package BehavioralPatterns.CommandPattern.shop;import BehavioralPatterns.CommandPattern.Drink;
import BehavioralPatterns.CommandPattern.TeaShop;/*** @author Zeyu Wan* @version 1.0.0* @ClassName YiDianDian.java* @Description 一点点类* @createTime 2022年03月16日 14:57:00*/
public class YiDianDian implements TeaShop {private Drink drink;public YiDianDian(Drink drink){this.drink = drink;}@Overridepublic void makeTea() {drink.drink();}
}

然后定义一个饮料接口,来真实的实现具体的饮料制作:

package BehavioralPatterns.CommandPattern;/*** @author Zeyu Wan* @version 1.0.0* @ClassName Drink.java* @Description 饮料接口* @createTime 2022年03月16日 14:49:00*/
public interface Drink {/*** 实现饮料制作*/public void drink();
}

具体的奶茶制作:

椰果奶茶:

package BehavioralPatterns.CommandPattern.drink;import BehavioralPatterns.CommandPattern.Drink;/*** @author Zeyu Wan* @version 1.0.0* @ClassName CoconutMilkTea.java* @Description 椰果奶茶类* @createTime 2022年03月16日 14:52:00*/
public class CoconutMilkTea implements Drink {@Overridepublic void drink() {System.out.println("椰果奶茶做好了");}
}

烧仙草:

package BehavioralPatterns.CommandPattern.drink;import BehavioralPatterns.CommandPattern.Drink;/*** @author Zeyu Wan* @version 1.0.0* @ClassName HerbalJelly.java* @Description 烧仙草类* @createTime 2022年03月16日 14:53:00*/
public class HerbalJelly implements Drink {@Overridepublic void drink() {System.out.println("烧仙草做好了");}
}

杨枝甘露:

package BehavioralPatterns.CommandPattern.drink;import BehavioralPatterns.CommandPattern.Drink;/*** @author Zeyu Wan* @version 1.0.0* @ClassName YojiNectar.java* @Description 杨枝甘露类* @createTime 2022年03月16日 14:51:00*/
public class YojiNectar implements Drink {@Overridepublic void drink() {System.out.println("杨枝甘露做好了");}
}

之后创建一个美团订单中心,实现总的订单添加删除以及下单功能,负责与奶茶店交互,避免了下订单的人喝奶茶店交互。

package BehavioralPatterns.CommandPattern;import java.util.ArrayList;
import java.util.List;/*** @author Zeyu Wan* @version 1.0.0* @ClassName OrderCenter.java* @Description 订单中心* @createTime 2022年03月16日 14:58:00*/
public class OrderCenter {private List<TeaShop> orderList = new ArrayList<>();/*** 添加订单* @param teaShop 奶茶店订单* @return 是否添加成功*/public boolean addOrder(TeaShop teaShop){return orderList.add(teaShop);}/*** * @param teaShop 奶茶店订单* @return 是否删除成功*/public boolean removeOrder(TeaShop teaShop){return orderList.remove(teaShop);}/*** 下单*/public synchronized void placeOrder(){for (TeaShop teashop:orderList) {teashop.makeTea();}orderList.clear();}
}

测试一下:

package BehavioralPatterns.CommandPattern;import BehavioralPatterns.CommandPattern.drink.CoconutMilkTea;
import BehavioralPatterns.CommandPattern.drink.HerbalJelly;
import BehavioralPatterns.CommandPattern.drink.YojiNectar;
import BehavioralPatterns.CommandPattern.shop.ChaBaiDao;
import BehavioralPatterns.CommandPattern.shop.ShuYi;
import BehavioralPatterns.CommandPattern.shop.YiDianDian;/*** @author Zeyu Wan* @version 1.0.0* @ClassName CommonTest.java* @Description 测试类* @createTime 2022年03月16日 15:02:00*/
public class CommonTest {public static void main(String[] args) {//茶百道点杨枝甘露ChaBaiDao chaBaiDaoOrder = new ChaBaiDao(new YojiNectar());//书亦烧仙草点烧仙草ShuYi shuYiOrder = new ShuYi(new HerbalJelly());//一点点点椰果奶茶YiDianDian yiDianDianOrder = new YiDianDian(new CoconutMilkTea());//创建订单并添加商品OrderCenter userOrder = new OrderCenter();if (userOrder.addOrder(chaBaiDaoOrder)){System.out.println("商品添加成功");}if (userOrder.addOrder(shuYiOrder)){System.out.println("商品添加成功");}if (userOrder.addOrder(yiDianDianOrder)){System.out.println("商品添加成功");}//不想要一点点的订单了if (userOrder.removeOrder(yiDianDianOrder)){System.out.println("商品删除成功");}//下订单userOrder.placeOrder();}
}

优点:

  1. 降低系统的耦合度:命令模式将调用操作的对象与知道如何实现该操作的对象解耦。
  2. 命令是头等的对象。它们可像其他的对象一样被操纵和扩展。
  3. 组合命令:你可将多个命令装配成一个组合命令,即可以比较容易地设计一个命令队列和宏命令。一般说来,组合命令是组合模式的一个实例。
  4. 增加新的命令很容易,因为这无需改变已有的类。
  5. 可以方便地实现对请求的Undo和Redo。

缺点:

  • 使用命令模式可能会 导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。

《设计模式入门》 19.命令模式相关推荐

  1. Head First 设计模式中的命令模式 的一个错误

    最近在看Head First 设计模式,其中命令模式中有讲到实现撤销功能,并且作者还出了一道题, 下面的是书中习题: public class MarcoCommand implements Comm ...

  2. 【白话设计模式八】命令模式(Command)

    为什么80%的码农都做不了架构师?>>>    #0 系列目录# 白话设计模式 工厂模式 单例模式 [白话设计模式一]简单工厂模式(Simple Factory) [白话设计模式二] ...

  3. 设计模式入门(策略模式)

    [0]README 0.1)本文部分文字描述转自 "head first 设计模式",旨在学习 设计模式入门(策略模式) 的基础知识: 0.2)本文章节4和5的source cod ...

  4. 《Head First 设计模式》之命令模式——遥控器

    命令模式(Command) --将"请求"封装成对象,以便使用不同的请求.队列或者日志来参数化其他对象.命令模式也支持可撤销的操作. 要点 将发出请求的对象和执行请求的对象解耦. ...

  5. Head First Design Mode(2)-设计模式入门(策略模式)

    该系列文章系个人读书笔记及总结性内容,任何组织和个人不得转载进行商业活动! 设计模式入门: 欢迎来到设计模式世界: 我们会看到设计模式的用途和优点,再看看关键的OO原则,通过实例来了解模式是如何运作的 ...

  6. Head First 设计模式总结(六) 命令模式

    本文总结了<Head First 设计模式>中的命令模式 命令模式--将请求封装成"对象",以便使用不同的请求.队列或者日志来参数化其他对象.命令模式也支持撤销操作. ...

  7. 【源码分析设计模式 13】命令模式

    一.基本介绍 1.在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作时哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计 ...

  8. 设计模式笔记:命令模式

    首先看看命令模式的定义:命令模式将请求封装成对象,以便使用不同的请求.队列或者日志来参数化其他对象.命令模式也支持撤销的操作. 所谓参数化,我的理解是实际执行的对象,比如light(电灯).strer ...

  9. Head First 设计模式笔记 5.命令模式

    文章目录 设计要求 命令模式 实际实现 命令模式具体应用 设计要求 小明接到了新任务,要求设计一个遥控器,这个遥控器上面有七个插槽,每个插槽都有对应的开和关按钮.要求每个都能控制任意家电如灯,电视,电 ...

最新文章

  1. 构建一个LVS-DR模型的高性能集群,并实现Nginx、PHP、MySQL分离
  2. vim在每行行首或行尾添加或删除内容
  3. Android自定义Adapter的ListView的思路及代码
  4. java语法特点是什么意思_java的语法是什么意思
  5. BufferedWriterTest
  6. (转自ztp800201) Android - 自定义标题栏(在标题栏中增加按钮和文本居中)
  7. win11语言输入没反应怎么办 windows11语音输入没反应的解决方法
  8. 官网下载到离线的Adobe Acrobat Reader DC
  9. IPSEC 001 --- 原理简介
  10. zmap扫描mysql_基于zmap 的应用层扫描器 zgrab (一)
  11. 计算机数字媒体毕业论文,数字媒体技术毕业设计(关于数字媒体技术的论文)
  12. 图像常用的神经网络方法优缺点及应用总结
  13. 心跳检测的思路及代码
  14. C++语法学习笔记十四:派生类-调用顺序-访问等级-函数遮蔽
  15. 传奇私服服务器修改沙巴克时间,新手教程:如何修改沙巴克名称
  16. Focal Loss简述
  17. Arduino - 继电器
  18. 外媒所言非虚,苹果降价或许是真的在清库存
  19. html js设置颜色渐变效果,Javascript 颜色渐变效果的实现代码
  20. Python安装库的常用方法

热门文章

  1. 全集然文明nbsp;(请点击图标进…
  2. 详解坐标系及坐标变换--大地坐标系(一)
  3. 为了适应云数据库mySQL产品_金山云数据库RDSMySQL的产品功能大解析
  4. 瑞典皇家理工学院计算机学什么,瑞典皇家理工大学学科设置是怎样的?
  5. python解密m3u8没有声音_ts文件解密+python脚本m3u8下载
  6. Linux笔记:文本编辑器nano简单说明
  7. Reporting报表开发知识汇总[个人原创]
  8. 【OpenCV入门教程之一】 安装OpenCV:OpenCV 3.0、OpenCV 2.4.8、OpenCV 2.4.9 +VS 开发环境配置
  9. js rsa java解密_RSA使用js加密,使用java解密
  10. 一本通 1273:货币系统