命令模式属于23种设计模式中行为模式中的一个,它也是一种简单实用非常普遍的设计模式。
首先看下GOF对命令模式的定义:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。

命令模式主要应用于将行为调用者与实现者解耦。比如我们以前惯用的写代码的方式是LogicProcess logic = new LogicProcess(); 然后紧接着调用实现方法logic.process(),这种写法其实非常普遍,但这种写法把行为调用者和行为实现者耦合在了一起,一般情况下并没有什么问题的,但当调用逻辑比较复杂或则调用行为有多种实现时就非常不利于程序的扩展。

命令模式的适用场景描述:

(1)整个调用过程比较繁杂,或者存在多处这种调用。使用Command类对该调用加以封装,便于功能的再利用。

(2)调用前后需要对调用参数进行某些处理。

(3)调用前后需要进行某些额外处理,比如日志,缓存,记录历史操作等。

命令模式结构图如下:

命令模式的参与角色:
(1)抽象命令角色(Command):抽象命令,包含命令执行的抽象方法
(2)命令接收者(Receiver):命令接收者角色,它包含所有命令的具体行为实现方法。
(3)具体命令角色(ConcreteCommand):它包含一个命令接收者对象,并调用接收者的对象相应实现方法。
(4)命令调用者角色(Invoker):提供给客户端调用,接收客户端所传递的具体命令对象。

下面看具体代码实现:

1、第一个文件抽象命令角色:Command.java

/**
* 抽象命令接口
*/
public interface Command {/**
* 命令执行方法
*/
public void execute();
}

2、第二个文件命令接收者角色:Document.java

/**
* 命令接收者 Receiver
*/
public class Document {/**
* 操作实体对象
*/
public static StringBuffer sbr = new StringBuffer();
/**
* 计数器
*/
public static int count = 0;
/**
* 撤销实现方法
*/
public void undo(){System.out.println("调用撤销实现方法,字符串递减");
sbr.deleteCharAt(sbr.length()-1);
count --;
System.out.println("当前文本为:" + sbr.toString());
}
/**
* 恢复实现方法
*/
public void redo(){System.out.println("调用恢复实现方法,字符串递加");
this.sbr.append(count);
count ++;
System.out.println("当前文本为:" + sbr.toString());
}
/**
* 执行实现方法
*/
public void add(){System.out.println("调用执行实现方法,字符串递加");
this.sbr.append(count);
count ++;
System.out.println("当前文本为:" + sbr.toString());
}
}

3、第三个文件具体命令角色:AddCommand.java

/**
* 执行命令实现类
*/
public class AddCommand implements Command {/**
* 命令接受者对象
*/
public Document doucment;
/**
* 构造方法
* @param document
*/
public AddCommand(Document document){this.doucment = document;
}
@Override
public void execute() {// TODO Auto-generated method stub
this.doucment.add();
}

4、第四个文件具体命令角色:UndoCommand.java

/**
* 撤销命令实现类
*/
public class UndoCommand implements Command {/**
* 命令接受者对象
*/
public Document doucment;
/**
* 构造方法
* @param document
*/
public UndoCommand(Document document){this.doucment = document;
}
@Override
public void execute() {// TODO Auto-generated method stub
this.doucment.undo();
}
}

5、第五个文件具体命令角色:RedoCommand.java

/**
* 恢复命令实现类
*/
public class RedoCommand implements Command {/**
* 命令接受者对象
*/
public Document doucment;
/**
* 构造方法
* @param document
*/
public RedoCommand(Document document){this.doucment = document;
}
@Override
public void execute() {// TODO Auto-generated method stub
this.doucment.redo();
}
}

6、第六个文件调用者角色:Invoker.java

/**
* 提供给客户端的命令调用方法
* @author feng
*
*/
public class Invoker {/**
* 命令对象
*/
public Command command;
/**
* 命令设置方法
* @param command
*/
public void setCommand(Command cmd){this.command = cmd;
}
/**
* 命令执行方法
*/
public void execute(){this.command.execute();
}
}

7、第七个文件TestMain.java

/**
* 测试Main方法
*/
public class TestMain {public static void main(String args[]){Document doc = new Document(); //文档实体对象
AddCommand addCmd = new AddCommand(doc); //具体命令实体对象
UndoCommand undoCmd = new UndoCommand(doc); //具体命令实体对象
RedoCommand redoCmd = new RedoCommand(doc); //具体命令实体对象
Invoker invoker = new Invoker(); //调用者对象
invoker.setCommand(addCmd);
invoker.execute();
invoker.setCommand(addCmd);
invoker.execute();
invoker.setCommand(undoCmd);
invoker.execute();
invoker.setCommand(redoCmd);
invoker.execute();
}

虽然代码看似挺多,但其实命令模式的结构还是比较清晰的,总的来说命令模式的使用流程就是首先创建一个抽象命令,然后创建多个具体命令实现抽象命令接口,然后创建一个命令接受者角色,它包含各种的行为的具体实现,然后再有一个命令调用者角色,提供给客户端,用于接收客户端的参数。

下面总结下命令模式的优点:

(1)命令模式将行为调用者和各种行为分隔开,降低程序的耦合,便于程序扩展。
(2)命令模式将行为的具体实现封装起来,客户端无需关心行为的具体实现。
(3)命令模式可为多种行为提供统一的调用入口,便于程序对行为的管理和控制。

java execute 执行成功_【JAVA】设计模式之命令模式(Command模式)的使用分析相关推荐

  1. java 并行 执行进度_关于java:Java8流的顺序执行和并行执行产生不同的结果?

    在Java8中运行以下流示例: System.out.println(Stream .of("a","b","c","d" ...

  2. java 模仿支付成功_我的大学到研究生自学 Java 之路,过程艰辛,不放弃,保持热情,最终发现我是这样拿到大厂 offer 的!...

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:本人真实经历:面试了20家大厂之后,发现这样介绍项目经验,显得项目很牛逼! 这一部分,其实,以前在自己的公众号写 ...

  3. java exec执行tar_用java调用rpmbuild 报错,同一条命令直接复制到终端却能运行

    用java调用rpmbuild 报错,同一条命令直接复制到终端却能运行. 命令如下: rpmbuild --define "_topdir /var/lib/jenkins/workspac ...

  4. java 基础面试 英文_[Java面试] 面试java基础总结大全

    原标题:[Java面试] 面试java基础总结大全 基础知识: 1.JVM.JRE和JDK的区别: JVM(Java Virtual Machine):java虚拟机,用于保证java的跨平台的特性. ...

  5. java 字符串格式替换_[Java] - 格式字符串替换方法

    Java 字符串格式替换方法有两种,一种是使用String.format(...),另一种是使用MessageFormat.format(...) 如下: import java.text.Messa ...

  6. java得到相对路径_[Java]JAVA获取相对路径问题的解决

    1.基本概念的理解 绝对路径:绝对路径就是你的主页上的文件或目录在硬盘上真正的路径,(URL和物理路径)例如: C:xyz est.txt 代表了test.txt文件的绝对路径.http://www. ...

  7. java t安装配置_[JAVA] JAVA JDK 安装配置

    JDK 安装 下载安装 下载JDK 从oracle官方网站下载并安装JDK. 下载使用文档 从oracle官方网站下载使用帮助文档. 安装库源文件 源文件位于安装目录的 /Library/Java/J ...

  8. java调用javascript函数_[Java教程]JavaScript函数的4种调用方法详解

    [Java教程]JavaScript函数的4种调用方法详解 0 2016-08-09 00:00:12 在JavaScript中,函数是一等公民,函数在JavaScript中是一个数据类型,而非像C# ...

  9. java 内存泄露 书籍_[Java教程]一次艰难的内存泄露排查,BeanUtils 的锅

    [Java教程]一次艰难的内存泄露排查,BeanUtils 的锅 0 2020-10-29 18:24:42 现象 通过jstat -gcutil pid 5000 ,发现fgc次数很多而且频繁,此时 ...

最新文章

  1. mysql出现多线程操作同一个表的情况,应该怎么办?
  2. Java的流读一行丢一行_java – 在少数特定情况下记录丢失的消息
  3. android应用开发(16)---AndroidManifest.xml
  4. post请求需要加密吗_你需要吗?这款闪存盘不仅可以专业加密,还能云备份
  5. vue状态管理存取数据_Vue中的数据通信和状态管理
  6. 参观移动公司机房感想
  7. 射线 ray linerender spotlight
  8. 使用QueenSono从ICMP提取数据
  9. python调用通达信公式_python读取通达信公式结果
  10. 领导的这些职场暗语,你一定要知道!
  11. p值小于0.05拒绝还是接受_p值的困惑
  12. 情侣的网站代码java_GitHub - 90x64/lovers-website: 程序员的情侣网站 (programmer's website of lovers)...
  13. 运行中的Docker容器添加映射端口
  14. html电影详情页面,电影
  15. 程序设计思维与实践月模拟题X3
  16. YOLO5的数据增强和权重设置hyp.scratch-med.yaml文件解读,degrees角度旋转和水平、垂直翻转解释
  17. 一分钟搞懂逻辑运算符(并且) , |(或者) , !(非) , ^(异或) , (短路与) , ||(短路或)之间的关系
  18. 地理信息系统入门基础篇(二)---地图投影
  19. 博客系统—头像预览功能实现
  20. 计算机修改用户权限,电脑时间的修改权限

热门文章

  1. Python中的字典(Dictionary)
  2. Opatch java 路径_Windows平台下opatch apply报错:OUI-67073
  3. java判断用户是否在某一个区域登录_单点登录实现原理
  4. css的类选择器#和id选择器.
  5. ftp ---- vsftpd安装卸载
  6. h5select动态加载数据_HTML5+中动态构建列表并填充数据
  7. java jdk包_Java开发工具包JDK的简介
  8. wampserver mysql乱码_ajax +json +php提交mysql数据库 中文乱码(wamp server 本地测试)求解?...
  9. 浪潮通信收入_浪潮获2019大数据“星河(Galaxy)”奖
  10. mysql导入社工库文件_社工库-数据表结构设计和数据导入