命令模式(Command),将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。

代码如下:

1 /**
2  * 抽象命令角色类
3  */
4 public interface Command {
5     /**
6      * 执行方法
7      */
8     void execute();
9 }

 1 /**
 2  * 接收者角色类
 3  */
 4 public class Receiver {
 5     /**
 6      * 真正执行命令相应的操作
 7      */
 8     public void action(){
 9         System.out.println("执行操作");
10     }
11 }

 1 /**
 2  * 具体命令角色类
 3  */
 4 public class ConcreteCommand implements Command {
 5
 6     //持有相应的接收者对象
 7     private Receiver receiver = null;
 8
 9     /**
10      * 构造方法
11      *
12      * @param receiver
13      */
14     public ConcreteCommand(Receiver receiver) {
15         this.receiver = receiver;
16     }
17
18
19     @Override
20     public void execute() {
21         //通常会转调用接收者对象的相应方法,让接收者来真正执行功能
22         receiver.action();
23     }
24 }

 1 /**
 2  * 请求者角色类
 3  */
 4 public class Invoker {
 5     /**
 6      * 持有命令对象
 7      */
 8     private Command command=null;
 9
10     /**
11      * 构造方法
12      * @param command
13      */
14     public Invoker(Command command) {
15         this.command = command;
16     }
17
18     /**
19      * 行动方法
20       */
21     public void action(){
22         command.execute();
23     }
24 }

 1 /**
 2  * 客户端
 3  */
 4 public class Client {
 5     public static void main(String[] args) {
 6         //创建接收者
 7         Receiver receiver=new Receiver();
 8         //创建命令对象,设定它的接收者
 9         Command command=new ConcreteCommand(receiver);
10         //创建请求者,把命令对象设置进去
11         Invoker invoker=new Invoker(command);
12         //执行方法
13         invoker.action();
14     }
15 }

以下例子是《大话设计模式》中的例子:

 1 /**
 2  * 烤串者(命令执行者)
 3  */
 4 public class Barbecuer {
 5     public void bakeMutton(){
 6         System.out.println("烤羊肉串");
 7     }
 8     public void bakeChickenWing(){
 9         System.out.println("烤鸡翅");
10     }
11 }

 1 /**
 2  * 抽象命令类
 3  */
 4 public abstract class Command {
 5     //抽象命令类,只需要确定‘烤肉串者'是谁
 6     protected Barbecuer receiver;
 7
 8     /**
 9      *
10      * @param receiver 参数为命名执行人
11      */
12     public Command(Barbecuer receiver) {
13         this.receiver = receiver;
14     }
15
16     //执行命令
17     abstract public void excuteCommand();
18 }

 1 /**
 2  * 烤鸡翅命令
 3  */
 4 public class BakeChickenWingCommand extends Command {
 5     public BakeChickenWingCommand(Barbecuer receiver) {
 6         super(receiver);
 7     }
 8
 9     @Override
10     public void excuteCommand() {
11         receiver.bakeChickenWing();
12     }
13 }

 1 /**
 2  * 烤羊肉串命令
 3  */
 4 public class BakeMuttonCommand extends Command {
 5
 6     public BakeMuttonCommand(Barbecuer receiver) {
 7         super(receiver);
 8     }
 9
10     @Override
11     public void excuteCommand() {
12         receiver.bakeMutton();
13     }
14 }

 1 /**
 2  * 服务员类
 3  */
 4 public class Waiter {
 5     private List<Command> orders=new ArrayList<>();
 6     /**
 7      * 不管用户想要什么烤肉,反正都是命令,只管记录订单,然后通知烤肉者执行
 8      * @param command
 9      */
10     public void setOrder(Command command){
11         orders.add(command);
12         System.out.println("增加订单:"+command.toString()+" 时间:"+new Date());
13     }
14     public void cancelOrder(Command command){
15         orders.remove(command);
16         System.out.println("取消订单:"+command.toString()+" 时间:"+new Date());
17     }
18     //通知执行
19     public void notifyExcuteCommand(){
20         for (Command command:orders
21              ) {
22             command.excuteCommand();
23         }
24
25     }
26 }

 1 public class Client {
 2     public static void main(String[] args) {
 3         //命令执行人
 4         Barbecuer boy=new Barbecuer();
 5         Command bakeMuttonCommand1=new BakeMuttonCommand(boy);
 6         Command bakeMuttonCommand2=new BakeMuttonCommand(boy);
 7         Command bakeChickenWingCommand1=new BakeChickenWingCommand(boy);
 8         //命令布人
 9         Waiter girl=new Waiter();
10
11         //开门营业
12         //记录订单命令
13         girl.setOrder(bakeMuttonCommand1);
14         girl.setOrder(bakeMuttonCommand2);
15         girl.setOrder(bakeChickenWingCommand1);
16
17         //点菜完毕,通知厨房(下达命令)
18         girl.notifyExcuteCommand();
19         girl.cancelOrder(bakeChickenWingCommand1);
20     }
21 }

命令模式作用

第一,它能较容易地设计一个命令队列;

第二,在需要的情况下,可以较容易地将命令记入日志;

第三,允许接收请求的一方决定是否要否决请求。

第四,可以容易地实现对请求的撤销和重做。

第五,由于加新的具体命令类不影响其他类,因此增加新的具体命令类很容易。

命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分割开。

转载于:https://www.cnblogs.com/gousheng107/p/8126814.html

一天学习一个设计模式之命令模式相关推荐

  1. 设计模式 之 命令模式

    2019独角兽企业重金招聘Python工程师标准>>> 设计模式 之 命令模式 命令模式比较简单,不过多赘述 为什么需要命令模式 将"行为请求者"与"行 ...

  2. 乐在其中设计模式(C#) - 命令模式(Command Pattern)

    原文:乐在其中设计模式(C#) - 命令模式(Command Pattern) [索引页] [源码下载] 乐在其中设计模式(C#) - 命令模式(Command Pattern) 作者:webabcd ...

  3. 设计模式之命令模式(行为型)

    目录 一.模式定义 二.模式角色 三.模式分析 四.典型例子 五.适用场景 一.模式定义 命令模式(Command Pattern):将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分离,两 ...

  4. 【Go实现】实践GoF的23种设计模式:命令模式

    上一篇:[Go实现]实践GoF的23种设计模式:代理模式 简单的分布式应用系统(示例代码工程):https://github.com/ruanrunxue/Practice-Design-Patter ...

  5. 每日学一个设计模式1——迭代器模式

    引言 精通设计模式是从码农脱颖而出的条件之一.跟着<图解设计模式>这本书学习设计模式,从今天开始,一天总结一个设计模式. 迭代器模式(一个一个遍历) 用处 隐藏遍历集合的内部结构,遍历不同 ...

  6. 23种设计模式之命令模式和策略模式的区别

    文章目录 概述 命令模式 策略模式 相同点 总结 概述 命令模式和策略模式确实很相似,只是命令模式多了一个接收者(Receiver)角色.它们虽然同为行为类模式,但是两者的区别还是很明显的.策略模式的 ...

  7. 每天一个设计模式之组合模式

    作者按:<每天一个设计模式>旨在初步领会设计模式的精髓,目前采用javascript和python两种语言实现.诚然,每种设计模式都有多种实现方式,但此小册只记录最直截了当的实现方式 :) ...

  8. 23种设计模式之命令模式

    命令模式的定义 定义: 将一个请求封装成一个对象, 从而让你使用不同的请求将客户端参数化, 对请求排队或者记录请求日志, 可以提供命令的撤销和恢复功能 通俗的说, 就是当有不同的请求时, 将每一种请求 ...

  9. 玉帝传美猴王上天,大闹天宫之Java设计模式:命令模式

    命令模式 示例 改进代码 命令模式 定义 意图 主要解决问题 何时使用 优缺点 玉帝传美猴王上天 命令模式和策略模式的区别 示例 系统需要设计一个命令行界面,用户可输入命令来执行某项功能,系统的功能会 ...

最新文章

  1. python3 函数签名简介 验证函数参数
  2. RTEMS 4.9.4 bootcard.c 中的 boot_card 函数分析
  3. Android成长日记-使用GridView显示多行数据
  4. 信息安全系统设计基础第三周学习总结—20135227黄晓妍
  5. 在JVM中记录世界停顿
  6. ajax时间控件,带有ajax的JQuery中的插件datetimepicker出错
  7. 启动kafka报错:__consumer_offsets-22\00000000000000000000.index.swap: 另一个程序正在使用此文件,进程无法访问。
  8. 服务器Windows 2008 R2 安装SQL 2008 R2
  9. GET,POST请求
  10. MySQL 效能监控工具--mysqlreport -转
  11. Ubuntu安装OpenCV4记录
  12. SPSS——秩和检验
  13. 梅兰商城案例代码编写(自己练习,纯手写,最后附有结果图以及精灵图)
  14. 实测 | 分羹无线市场 天融信无线AP究竟有多强?
  15. 通过uart串口和printf函数打印
  16. 苏宁搭台品牌唱戏,净水市场将变天
  17. Tetrate万凯:SkyWalking MAL的监控虚拟机和Kubernetes实践
  18. Element UI是什么?基本用法
  19. hive中如何判断字符串是否是数字
  20. iTunes更新Iphone上的软件

热门文章

  1. java cellvalue_Java Cell.getErrorCellValue方法代码示例
  2. 【Pytorch神经网络基础理论篇】 05 矩阵计算
  3. git 提交文件_git原理与实战
  4. 三、案例:留言板 url.parse()
  5. 一、操作系统——处理机(作业)调度算法:先来先服务算法FCFS、最短作业优先算法SJF(非抢占式)、 最短剩余时间优先算法SRTN(抢占式)、最高响应比优先算法HRRN
  6. LeetCode 1808. 好因子的最大数目(整数拆分,乘积最大)
  7. TensorFlow 2.0 - 张量/自动求导/梯度下降
  8. LeetCode 1487. 保证文件名唯一(哈希map)
  9. LeetCode 1015. 可被 K 整除的最小整数(数学)
  10. 程序员面试金典 - 面试题 16.11. 跳水板(数学)