文档章节

java设计模式——命令模式

MYangM
 MYangM
发布于 2017/06/02 16:24
字数 1280
阅读 1
收藏 0

命令模式属于23种设计模式中行为模式中的一个,它也是一种简单实用非常普遍的设计模式。
首先看下GOF对命令模式的定义:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
命令模式主要应用于将行为调用者与实现者解耦。比如我们以前惯用的写代码的方式是LogicProcess logic = new LogicProcess();  然后紧接着调用实现方法logic.process(),这种写法其实非常普遍,但这种写法把行为调用者和行为实现者耦合在了一起,一般情况下并没有什么问题的,但当调用逻辑比较复杂或则调用行为有多种实现时就非常不利于程序的扩展。
命令模式的适用场景描述:
(1)整个调用过程比较繁杂,或者存在多处这种调用。使用Command类对该调用加以封装,便于功能的再利用。
(2)调用前后需要对调用参数进行某些处理。
(3)调用前后需要进行某些额外处理,比如日志,缓存,记录历史操作等。
命令模式结构图如下:

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

点击(此处)折叠或打开

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

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

点击(此处)折叠或打开

  1. /**
  2.  * 命令接收者 Receiver
  3.  */
  4. public class Document {
  5.  
  6.     /**
  7.      * 操作实体对象
  8.      */
  9.     public static StringBuffer sbr = new StringBuffer();
  10.     
  11.     /**
  12.      * 计数器
  13.      */
  14.     public static int count = 0;
  15.     
  16.     /**
  17.      * 撤销实现方法
  18.      */
  19.     public void undo(){
  20.         System.out.println("调用撤销实现方法,字符串递减");
  21.         sbr.deleteCharAt(sbr.length()-1);
  22.         count --;
  23.         System.out.println("当前文本为:" + sbr.toString());
  24.     }
  25.     
  26.     /**
  27.      * 恢复实现方法
  28.      */
  29.     public void redo(){
  30.         System.out.println("调用恢复实现方法,字符串递加");
  31.         this.sbr.append(count);
  32.         count ++;
  33.         System.out.println("当前文本为:" + sbr.toString());
  34.     }
  35.     
  36.     /**
  37.      * 执行实现方法
  38.      */
  39.     public void add(){
  40.         System.out.println("调用执行实现方法,字符串递加");
  41.         this.sbr.append(count);
  42.         count ++;
  43.         System.out.println("当前文本为:" + sbr.toString());
  44.     }
  45. }

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

点击(此处)折叠或打开

  1. /**
  2.  * 执行命令实现类
  3.  */
  4. public class AddCommand implements Command {
  5.  
  6.     /**
  7.      * 命令接受者对象
  8.      */
  9.     public Document doucment;
  10.     
  11.     /**
  12.      * 构造方法
  13.      * @param document
  14.      */
  15.     public AddCommand(Document document){
  16.         this.doucment = document;
  17.     }
  18.     
  19.     @Override
  20.     public void execute() {
  21.         // TODO Auto-generated method stub
  22.         this.doucment.add();
  23.     }
  24. }

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

点击(此处)折叠或打开

  1. /**
  2.  * 撤销命令实现类
  3.  */
  4. public class UndoCommand implements Command {
  5.  
  6.     /**
  7.      * 命令接受者对象
  8.      */
  9.     public Document doucment;
  10.     
  11.     /**
  12.      * 构造方法
  13.      * @param document
  14.      */
  15.     public UndoCommand(Document document){
  16.         this.doucment = document;
  17.     }
  18.     
  19.     @Override
  20.     public void execute() {
  21.         // TODO Auto-generated method stub
  22.         this.doucment.undo();
  23.     }
  24. }

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

点击(此处)折叠或打开

  1. /**
  2.  * 恢复命令实现类
  3.  */
  4. public class RedoCommand implements Command {
  5.  
  6.     /**
  7.      * 命令接受者对象
  8.      */
  9.     public Document doucment;
  10.     
  11.     /**
  12.      * 构造方法
  13.      * @param document
  14.      */
  15.     public RedoCommand(Document document){
  16.         this.doucment = document;
  17.     }
  18.     
  19.     @Override
  20.     public void execute() {
  21.         // TODO Auto-generated method stub
  22.         this.doucment.redo();
  23.     }
  24.  
  25. }

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

点击(此处)折叠或打开

  1. /**
  2.  * 提供给客户端的命令调用方法
  3.  * @author feng
  4.  *
  5.  */
  6. public class Invoker {
  7.  
  8.     /**
  9.      * 命令对象
  10.      */
  11.     public Command command;
  12.     
  13.     /**
  14.      * 命令设置方法
  15.      * @param command
  16.      */
  17.     public void setCommand(Command cmd){
  18.         this.command = cmd;
  19.     }
  20.     
  21.     /**
  22.      * 命令执行方法
  23.      */
  24.     public void execute(){
  25.         this.command.execute();
  26.     }
  27. }

7、第七个文件TestMain.java

点击(此处)折叠或打开

  1. /**
  2.  * 测试Main方法
  3.  */
  4. public class TestMain {
  5.  
  6.     public static void main(String args[]){
  7.         Document doc = new Document(); //文档实体对象
  8.         AddCommand addCmd = new AddCommand(doc); //具体命令实体对象
  9.         UndoCommand undoCmd = new UndoCommand(doc); //具体命令实体对象
  10.         RedoCommand redoCmd = new RedoCommand(doc); //具体命令实体对象
  11.         Invoker invoker = new Invoker(); //调用者对象
  12.         invoker.setCommand(addCmd);
  13.         invoker.execute();
  14.         invoker.setCommand(addCmd);
  15.         invoker.execute();
  16.         invoker.setCommand(undoCmd);
  17.         invoker.execute();
  18.         invoker.setCommand(redoCmd);
  19.         invoker.execute();
  20.     }
  21. }

虽然代码看似挺多,但其实命令模式的结构还是比较清晰的,总的来说命令模式的使用流程就是首先创建一个抽象命令,然后创建多个具体命令实现抽象命令接口,然后创建一个命令接受者角色,它包含各种的行为的具体实现,然后再有一个命令调用者角色,提供给客户端,用于接收客户端的参数。
下面总结下命令模式的优点:
(1)命令模式将行为调用者和各种行为分隔开,降低程序的耦合,便于程序扩展。
(2)命令模式将行为的具体实现封装起来,客户端无需关心行为的具体实现。
(3)命令模式可为多种行为提供统一的调用入口,便于程序对行为的管理和控制。

本文转载自:http://blog.chinaunix.net/uid-29140694-id-4134135.html

共有 人打赏支持
MYangM
粉丝 0
博文 39
码字总数 1656
作品 0
闵行
从 Java 到 Scala (三): object 的应用

本文由 Captain 发表在 ScalaCool 团队博客。 在上篇 Java 到 Scala 系列中,我想你或多或少在语言特性上对有了一定的掌握,在了解完它酷酷的语言特性——让静态回归常态并能简单运用其衍生出...

ScalaCool
09/10
0
0
编程中的那些套路——关于单例模式

该文章属于《编程中的那些经典套路——设计模式汇总》系列,并且以下内容基于语言PHP 在设计模式中,单例模式和工厂模式)可以说是使用的最普遍的设计模式了,所以掌握此种模式尤为重要。 单...

gzchen
08/27
0
0
设计模式15——Template Method设计模式

Template Method模板方法设计模式定义一个操作中算法的骨架,将具体步骤的执行延迟到子类中实现。Java中的抽象类就是使用了模板方法设计模式。模板方法设计模式结构如下: 以文档处理为例,T...

小米米儿小
2014/01/24
0
0
练就Java24章真经—你所不知道的工厂方法

前言 最近一直在Java方向奋斗《终于,我还是下决心学Java后台了》,今天抽空开始学习Java的设计模式了 。计划有时间就去学习,你这么有时间,还不来一起上车吗? 之所以要学习Java模式,是因...

codeGoogle
09/04
0
0
设计模式3——Proxy设计模式

Proxy代理设计模式是一种控制对象访问的设计模式,类似于网络代理,网络代理机制如下图: Proxy代理设计模式机制如下: 代理模式UML图如下: 代理模式顺序图如下: 客户端程序通过代理程序来...

小米米儿小
2013/12/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Thinkphp5 优雅配置两个数据库

工作需要需要配置两个数据库,框架5.0的,步骤如下: 1、在database.php同级创建一个database2.php文件 在里面配置第二个数据库信息, 2、在config中配置这个数据库信息: 3、创建第二个表的...

wqzbxh
15分钟前
1
0
Socket网络编程进阶与实战

Socket网络编程进阶与实战 Socket对于每个工程师的重要性不言而喻。本课程将理论结合实践,带你从零开始,系统学习Socket编程技术,让Socket的学习不再那么零散与难以掌握,同时会提炼出Soc...

qq__2304636824
21分钟前
1
0
Android studio常用快捷键

Ctrl +Alt +Space //显示可用参数 Ctrl + Alt +M //抽取方法 Ctrl +Alt + F //提取全局变量 Ctrl +Shift + "+或-" //折叠/展开代码块 Shift + F6 //批量更改变量 Ctrl + Tab //切换器 Ctrl +...

lanyu96
33分钟前
2
0
@ControllerAdvice 拦截异常并统一处理

在spring 3.2中,新增了@ControllerAdvice 注解,可以用于定义@ExceptionHandler、@InitBinder、@ModelAttribute,并应用到所有@RequestMapping中。 一、介绍 创建 MyControllerAdvice,并添...

狼王黄师傅
37分钟前
1
0
ajax传递参数给springmvc总结[转]

https://www.cnblogs.com/franson-2016/p/6770028.html https://www.cnblogs.com/xiaoxi/p/5708084.html 总结: 1.springmvc与Ajax交互,可以传入三种类型的数据: (1)文本:"uname=alice&......

废柴
39分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部