LieBrother原文: 行为型模式:命令模式

十一大行为型模式之三:命令模式。

简介

姓名 :命令模式

英文名 :Command Pattern

价值观 :军令如山

个人介绍

Encapsulate a request as an object,thereby letting you parameterize clients with different requests,queue or log requests,and support undoable operations. 将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。 (来自《设计模式之禅》)

你要的故事

作为一个程序猿,我们每天都在经历着命令模式,技术经理把需求任务分配给工程师开发,有时因为第三方或者其他不可抗拒的因素导致需求停止开发。这种工作模式就是命令模式。好了,开始故事了。小明在 XX 科技公司做一个安静的程序猿,有一天技术经理给他分配了一个任务:新增黑名单,也就是在他们系统的某个模块里面可以手工对电话打黑名单标签的功能。小明接到任务后就立马开发,在开发了 2 天之后,因为战略原因,技术经理大明暂停了这个开发任务,接下来我们通过非命令模式和命令模式 2 种代码实现来体现这个过程。在这个场景中,为了简单,我们假定技术经理大明手下只有小明一个开发人员。

非命令模式

非命令模式也就是不使用命令模式的代码实现。代码中,我们出现了 Developer 开发人,开发同学是接受技术经理传达的任务,技术经理让他开发哪个需求就开发哪个需求,如果项目有问题需要中断,也需要技术经理评估后传达给开发同学,所以 Developer 有 2 个方法,分别是 develop() 开发需求和 suspend() 暂停需求。 Requirement 则为需求类,TechnicalManager1 则为技术经理类,他有一个方法 action(),通过这个方法来指定开发同学开发任务或者暂停任务。

public class NoCommandTest {public static void main(String[] args) {Developer xiaoMing = new Developer("小明");Requirement requirement = new Requirement("新增黑名单");TechnicalManager1 technicalManager2 = new TechnicalManager1("大明");technicalManager2.setDeveloper(xiaoMing);technicalManager2.action(requirement, "develop");System.out.println("开发了 2 天,需求变故,需要暂停。。。");technicalManager2.action(requirement, "suspend");}}/*** 开发人员*/
class Developer {private String name;public Developer(String name) {this.name = name;}public void develop(Requirement requirement) {System.out.println(this.name + " 开始开发需求:" + requirement.getName());}public void suspend(Requirement requirement) {System.out.println(this.name + " 停止开发需求:" + requirement.getName());}public String getName() {return name;}}/*** 需求*/
class Requirement {private String name;public Requirement(String name) {this.name = name;}public String getName() {return name;}}/*** 技术经理*/
class TechnicalManager1 {private String name;private Developer developer;public TechnicalManager1(String name) {this.name = name;}public void setDeveloper(Developer developer) {this.developer = developer;}public void action(Requirement requirement, String type) {if ("develop".equals(type)) {this.developer.develop(requirement);} else if ("suspend".equals(type)) {this.developer.suspend(requirement);}}}打印结果:
小明 开始开发需求:新增黑名单
开发了 2 天,需求变故,需要暂停。。。
小明 停止开发需求:新增黑名单
复制代码

通过代码,我们可以发现技术经理和开发同学是强依赖关系。如果技术经理下达了一个任务,要求小明写一下周报,这时候得怎么写?是不是小明需要一个写周报的方法,大明也需要新增一个处理事务类型?有没有更好的方法让技术经理不需要做任何改变?命令模式就来解决这个问题。

命令模式

在这个例子中,不管大明叫小明做什么事情,其实都是一样的,就是下达任务命令,让小明去执行命令。我们可以利用命令模式把下达任务这个抽象起来,当做父类,下达开发命令、下达暂停命令、下达写周报等等都是不同的子命令。代码如下。

public class CommandTest {public static void main(String[] args) {Developer xiaoMing = new Developer("小明");Command developCommand = new DevelopCommand(xiaoMing);Command suspendCommand = new SuspendCommand(xiaoMing);Requirement requirement = new Requirement("新增黑名单");TechnicalManager2 technicalManager = new TechnicalManager2("大明");technicalManager.setCommand(developCommand);technicalManager.action(requirement);System.out.println("开发了 2 天,需求变故,需要暂停。。。");technicalManager.setCommand(suspendCommand);technicalManager.action(requirement);}}/*** 命令*/
abstract class Command {protected Developer developer;public Command(Developer developer) {this.developer = developer;}public abstract void execute(Requirement requirement);
}/*** 开始开发*/
class DevelopCommand extends Command {public DevelopCommand(Developer developer) {super(developer);}@Overridepublic void execute(Requirement requirement) {this.developer.develop(requirement);}
}/*** 开发中断*/
class SuspendCommand extends Command {public SuspendCommand(Developer developer) {super(developer);}@Overridepublic void execute(Requirement requirement) {this.developer.suspend(requirement);}
}/*** 技术经理*/
class TechnicalManager2 {private String name;private Command command;public TechnicalManager2(String name) {this.name = name;}public void action(Requirement requirement) {this.command.execute(requirement);}public void setCommand(Command command) {this.command = command;}
}打印结果:
小明 开始开发需求:新增黑名单
开发了 2 天,需求变故,需要暂停。。。
小明 停止开发需求:新增黑名单
复制代码

代码中用 Command 来抽象下达任务,而技术经理 TechnicalManager2 并没有和 Developer 有直接的关系,而是 TechnicalManager2 和 Command 建立的联系,Command 和 Developer 建立了联系。这样子把大明和小明的强依赖关系给剥离开,而新增一个下达写周报的任务也很简单,在 Developer 中新增一个处理写周报的方法,新增一个写周报的 Command 子类,就可以了,TechnicalManager2 如上面所愿不用修改。这就是完整的一个命令模式代码。

代码: Command Pattern

总结

从文章中我们就可以看到,利用命令模式能够进行类的解耦,让调用者和接受者没有任何关系,也通过对行为的抽象,让新增其他行为变得清晰容易,也就是可扩展性大大增加

参考资料:《大话设计模式》、《设计模式之禅》

推荐阅读:

公众号之设计模式系列文章

希望文章对您有所帮助,设计模式系列会持续更新,感兴趣的同学可以关注公众号:LieBrother,第一时间获取文章推送阅读,也可以一起交流,交个朋友。

行为型模式:命令模式相关推荐

  1. Java设计模式之行为型:命令模式

    前言: 在开发中,我们可能需要向某些对象发送一些请求,但我们不知道请求的具体接收者是谁,也不知道被请求的操作是哪个,只知道在系统运行中指定具体的请求接收者即可,打个比方,电视遥控器,我们只需知道按哪个 ...

  2. 设计模式-行为型模式-命令模式

    设计模式-行为型模式-命令模式 基础 以一个MIS系统为栗子 MIS 管理信息系统(Management Information System,MIS)是一个以人为主导的,利用计算机硬件.软件和网络设 ...

  3. 《设计模式详解》行为型模式 - 命令模式

    命令模式 6.3 命令模式 6.3.1 概述 6.3.2 结构 6.3.3 案例实现 6.3.4 优缺点 6.3.5 使用场景 6.3.6 JDK 源码 - Runnable 完整的笔记目录:< ...

  4. 设计模式 — 行为型模式 — 命令模式

    目录 文章目录 目录 命令模式 应用场景 代码示例 命令模式 命令模式的目的是解耦调用操作的对象(调用者)和提供实现的对象(接收者). 命令模式的思路是在调用者和接收者之间插入一个命令类(Comman ...

  5. 备忘录模式 命令模式_备忘录设计模式示例

    备忘录模式 命令模式 本文是我们名为" Java设计模式 "的学院课程的一部分. 在本课程中,您将深入研究大量的设计模式,并了解如何在Java中实现和利用它们. 您将了解模式如此重 ...

  6. 16、设计模式-行为型模式-命令模式

    命令模式(请求发送者与接收者解耦) 在软件开发中,我们经常需要向某些对象发送请求(调用其中的某个或某些方法),但是并 不知道请求的接收者是谁,也不知道被请求的操作是哪个,此时,我们特别希望能够以一种 ...

  7. 围观设计模式(23)--行为型之命令模式(Command Pattern)

    在面向对象程式设计的范畴中,命令模式是一种设计模式,它尝试以物件来代表实际行动.命令物件可以把行动(action) 及其参数封装起来,于是这些行动可以被: 重复多次 取消(如果该物件有实作的话) 取消 ...

  8. Java设计模式(代理模式-模板方法模式-命令模式)

    Java设计模式Ⅴ 1.代理模式 1.1 代理模式概述 1.2 静态代理 1.2.1 静态代理概述 1.2.2 代码理解 1.3 动态代理之JDK代理 1.3.1 动态代理之JDK代理概述 1.3.2 ...

  9. 行为模式(模板模式命令模式备忘录模式)

    目录 模板方法模式(Template) 介绍 实现 命令模式(Command) 介绍 实现 备忘录模式(Memento) 介绍 实现 模板方法模式(Template) 一个抽象类公开定义了执行它的方法 ...

  10. 『设计模式』再谈麦当劳的点单模式--命令模式(Command)

    23种设计模式+额外常用设计模式汇总 (持续更新) 麦当劳,我三期设计模式拿你举例子了,私信联系我打钱!!! 概述 命令模式又称为行动(Action) 模式或交易(Transaction) 模式. 命 ...

最新文章

  1. 需要注意变量作用域的使用
  2. GPUImageMovieWriter实现暂停录制,重新录制
  3. 10 分钟从零搭建个人博客
  4. ios10 申请拍照权限_iOS10配置申请权限
  5. 【ElasticSearch】Es 源码之 ScriptModule ScriptService 源码解读
  6. word2vec -- 负采样 -- skip-gram
  7. 易宝支付(Java实现)
  8. redis的管理和监控工具treeNMS
  9. 软件工程(需求分析)
  10. 关于USIM卡的全面测试综述
  11. 什么是ISO?ISO增值的作用
  12. 惠普暗影精灵II代pro进入biso
  13. spring事务的传播行为的讲解(笔记 侵删)
  14. scrapy爬虫入门:爬取《id97》电影
  15. 计算机网络实验二 路由器的配置和静态路由
  16. 华为开发者联盟生态市场企业特惠GO第1期—应用软件专题
  17. 基于 Sodor 的矩阵乘法加速器设计之C++
  18. 利用tkinter设计贷款计算器
  19. 鸿蒙是另一种安卓吗,鸿蒙不是另一个安卓或者iOS!鸿蒙2.0上线倒计时
  20. 联发科mt6165芯片原理图mt6165芯片资料

热门文章

  1. Linux TCP/IP协议栈笔记
  2. Linux网络编程中的几组类似功能的区别
  3. 【Python】深度学习中将数据按比例随机分成随机 训练集 和 测试集的python脚本
  4. 【Linux】延时函数sleep、usleep、nanosleep、select、pselect的比较
  5. 【Qt】在Qlayout中Qlabel::setScaledContents(true);失效
  6. 【linux驱动】嵌入式 Linux 对内存的直接读写(devmem)
  7. dsp和通用计算机的区别,dsp芯片是什么_dsp芯片和通用微处理器有什么区别
  8. win7能用的matlab,win7环境下使用matlab7.0(R14)方法
  9. div 自动换行_js自动打字--autotypejs
  10. 【spring】使用spring的环境配置及从官网获得配置文件所用代码的方法