`

java 设计模式--命令模式

    博客分类:
  • java
阅读更多

在程序设计中,经常设计到一个对象需要请求另外一个对象调用其方法达到某种目的,如果请求这不希望或不直接和被请求者打交道,既请求者不包含被请求者的引用,那么就可以使用命令模式。例如在军队中,指挥官请求三连偷袭敌人,但是指挥官不希望或无法直接与三连取得联系,那么可以将该请求形成一个命令,该命令的核心是让三连偷袭敌人。只要能让该命令被执行,就会实现偷袭敌人的目的。

命令模式是关于怎样处理一个对象请求到另一个对象调用其方法完成某项任务的一种成熟的模式,这里称提出请求的对象为请求者,被请求的对象为接收者。在命令模式中,当一个对象请求另一个对象其调用方法时,不和被请求的对象直接打交道,而是把这这种请求封装到一个命令的对象中,起封装的手段是将请求封装在命令对象的一个方法中。命令模式的核心就是使用命令对象来封装方法调用。既请求者的请求,接受者调用方法。

 

结构:
命令者模式包括四种角色
接收者:接受者是一个类的实例,该实例负责执行与请求相关的操作
命令:命令是一个接口,规定了用来封装请求的若干个方法。
具体命令:具体命令是实现命令接口的类的实例,具体命令必须实现命令接口中的方法。

请求者:请求者是一个包含”命令接口“变量的类的实例。请求者中的”命令“接口的变量可以存放任何具体命令的引用,请求者负责调用具体命令,让具体命令执行那些封装了请求的方法



代码实例:
接受者

 

[java] view plaincopy
 
  1. /** 
  2.  * 接受者:具体执行命令的人 
  3.  * @author hnylchf 
  4.  * 
  5.  */  
  6. public class Receiver {  
  7.   
  8.     public void sendMessage(){  
  9.         System.out.println("保证完成任务");  
  10.     }  
  11. }  


命令

 

 

[java] view plaincopy
 
  1. package org.zhy.command;  
  2.   
  3. /** 
  4.  * 命令,封装请求的方法 
  5.  * @author hnylchf 
  6.  * 
  7.  */  
  8. public interface Command {  
  9.   
  10.     public void exceute();  
  11. }  


请求者

 

 

[java] view plaincopy
 
  1. package org.zhy.command;  
  2.   
  3. /** 
  4.  * 请求者 
  5.  *  
  6.  * @author hnylchf 
  7.  *  
  8.  */  
  9. public class Invoker {  
  10.   
  11.     Command command;  
  12.   
  13.     public void startExceuteCommand(Command command) {  
  14.         this.command = command;  
  15.         command.exceute();  
  16.     }  
  17.   
  18.   
  19. }  


具体命令

 

 

[java] view plaincopy
 
  1. package org.zhy.command;  
  2.   
  3. /** 
  4.  * 具体命令 
  5.  *  
  6.  * @author hnylchf 
  7.  *  
  8.  */  
  9. public class ConcreteCommand {  
  10.   
  11.     Receiver receiver;  
  12.   
  13.     public ConcreteCommand(Receiver receiver) {  
  14.         this.receiver = receiver;  
  15.     }  
  16.   
  17.     public void execute() {  
  18.         receiver.sendMessage();  
  19.     }  
  20. }  


演示:

 

 

[java] view plaincopy
 
  1. package org.zhy.command;  
  2.   
  3. public class Appliction {  
  4.   
  5.     public static void main(String[] args) {  
  6.         Receiver receiver = new Receiver();  //执行者  
  7.         Command command = new ConcreteCommand(receiver); //命令和具体命令  
  8.         Invoker invoker = new Invoker(); //请求者  
  9.         invoker.startExceuteCommand(command); //请求者下达命令  
  10.     }  
  11. }  


命令接口的撤销方法
命令接口中规定了用来封装请求的方法比如上例的execute方法,命令接口中还可以提供用来封装撤销请求的方法。既撤销方法的执行能撤销execute方法的执行效果。如果execute方法的执行效果不可撤销,那么具体命令就不必实现撤销方法。


以下示例一个关于撤销方法的demo


命令:

 

 

[java] view plaincopy
 
  1. package org.zhy.commandundo;  
  2.   
  3. public interface Command {  
  4.   
  5.     public void execute(String name);  
  6.       
  7.     public void undo();  
  8. }  


具体命令:

 

 

[java] view plaincopy
 
  1. package org.zhy.commandundo;  
  2.   
  3. import java.util.ArrayList;  
  4.   
  5. public class ConcreteCommand implements Command {  
  6.   
  7.     ArrayList<String> dirNameList;  
  8.     MakeDir dir;  
  9.   
  10.     public ConcreteCommand(MakeDir dir) {  
  11.         dirNameList = new ArrayList<String>();  
  12.         this.dir = dir;  
  13.     }  
  14.   
  15.     @Override  
  16.     public void execute(String name) {  
  17.         dir.createDir(name);  
  18.         dirNameList.add(name);  //记录添加到list中  
  19.     }  
  20.   
  21.     @Override  
  22.     public void undo() {  
  23.         if (dirNameList != null && dirNameList.size() > 0) {  
  24.             String str = dirNameList.get(dirNameList.size() - 1);  
  25.             dir.deleteDir(str);  
  26.             dirNameList.remove(dirNameList.size() - 1);  
  27.         } else {  
  28.             System.out.println("没有需要操作的记录");  
  29.         }  
  30.   
  31.     }  
  32. }  


执行者

 

 

[java] view plaincopy
 
  1. package org.zhy.commandundo;  
  2.   
  3. import java.io.File;  
  4.   
  5. public class MakeDir {  
  6.   
  7.     public void createDir(String name) {  
  8.         File file = new File(name);  
  9.         file.mkdir();  
  10.     }  
  11.   
  12.     public void deleteDir(String name) {  
  13.         File file = new File(name);  
  14.         file.delete();  
  15.     }  
  16. }  


请求者

 

 

[java] view plaincopy
 
  1. package org.zhy.commandundo;  
  2.   
  3. public class RequestMakedir {  
  4.   
  5.     Command command;  
  6.   
  7.     public RequestMakedir(Command command) {  
  8.         this.command = command;  
  9.     }  
  10.   
  11.     public void startExecuteCommand(String name) {  
  12.         command.execute(name);  
  13.     }  
  14.   
  15.     public void undoExecuteCommand() {  
  16.         command.undo();  
  17.     }  
  18. }  


演示

 

 

[java] view plaincopy
 
  1. package org.zhy.commandundo;  
  2.   
  3. public class Appliction {  
  4.   
  5.     public static void main(String[] args) {  
  6.           
  7.         MakeDir dir = new MakeDir();  
  8.         Command command = new ConcreteCommand(dir);  
  9.         RequestMakedir requestMakedir = new RequestMakedir(command);  
  10.         requestMakedir.startExecuteCommand("jiafei");  
  11.         requestMakedir.startExecuteCommand("jiafei2");  
  12.         requestMakedir.startExecuteCommand("jiafei3");  
  13.         requestMakedir.undoExecuteCommand();  
  14.     }  
  15. }  


宏命令:
宏命令也是一个具体的命令,只不过他包含了其他命令的引用。当一个宏命令执行其execute方法时,将导致所引用的其他命令执行,因此执行一个宏命令相当于执行了多具体命令。


请求者输入英文字母或1-n之间的偶数可以请求既输出英文字母表,又输出1-n之间的偶数。
首先设计两个接收者,一个是输出英文字母表,一个是输出1-n之间的偶数
接收者1:打印英文字母

 

 

[java] view plaincopy
 
  1. package org.zhy.commandmacro;  
  2.   
  3. public class PrintLetter {  
  4.   
  5.     public void printEnglish() {  
  6.         for (char c = 'a'; c < 'z'; c++) {  
  7.             System.out.print(" " + c);  
  8.         }  
  9.     }  
  10. }  

接受者2:打印偶数

 

 

[java] view plaincopy
 
  1. package org.zhy.commandmacro;  
  2.   
  3. public class PrintNumber {  
  4.   
  5.     int n;  
  6.   
  7.     public PrintNumber(int n) {  
  8.         this.n = n;  
  9.     }  
  10.   
  11.     public void printEventNumber() {  
  12.         for (int i = 0; i <= n; i++) {  
  13.             if (i % 2 == 0) {  
  14.                 System.out.print(" " + i);  
  15.             }  
  16.         }  
  17.     }  
  18. }  


命令:

 

 

[java] view plaincopy
 
  1. package org.zhy.commandmacro;  
  2.   
  3. public interface Command {  
  4.   
  5.     public void execute();  
  6. }  


命令1:处理打印字母

 

 

 

[java] view plaincopy
 
  1. package org.zhy.commandmacro;  
  2.   
  3. public class PrintEnglishCommand implements Command {  
  4.   
  5.     PrintLetter letter;  
  6.   
  7.     public PrintEnglishCommand(PrintLetter letter) {  
  8.         this.letter = letter;  
  9.     }  
  10.   
  11.     @Override  
  12.     public void execute() {  
  13.         letter.printEnglish();  
  14.     }  
  15. }  



 

命令2:处理打印偶数

 

[java] view plaincopy
 
  1. package org.zhy.commandmacro;  
  2.   
  3. public class PrintNumberCommand implements Command {  
  4.   
  5.     PrintNumber number;  
  6.   
  7.     public PrintNumberCommand(PrintNumber number) {  
  8.         this.number = number;  
  9.   
  10.     }  
  11.   
  12.     @Override  
  13.     public void execute() {  
  14.         number.printEventNumber();  
  15.     }  
  16. }  


命令3:宏命令处理一批命令(打印字母和打印偶数)

 

 

[java] view plaincopy
 
  1. package org.zhy.commandmacro;  
  2.   
  3. import java.util.ArrayList;  
  4.   
  5. public class MacroCommand implements Command {  
  6.   
  7.     ArrayList<Command> commandList;  
  8.   
  9.     public MacroCommand(ArrayList<Command> commandList) {  
  10.         this.commandList = commandList;  
  11.     }  
  12.   
  13.     @Override  
  14.     public void execute() {  
  15.         for (Command command : commandList) {  
  16.             command.execute();  
  17.         }  
  18.     }  
  19.   
  20. }  


请求者

 

 

[java] view plaincopy
 
  1. package org.zhy.commandmacro;  
  2.   
  3. public class RequestPerson {  
  4.   
  5.     Command command;  
  6.   
  7.     public Command getCommand() {  
  8.         return command;  
  9.     }  
  10.   
  11.     public void setCommand(Command command) {  
  12.         this.command = command;  
  13.     }  
  14.   
  15.     public void startExecuteCommand() {  
  16.         command.execute();  
  17.     }  
  18. }  


演示

 

 

[java] view plaincopy
 
  1. package org.zhy.commandmacro;  
  2.   
  3. import java.util.ArrayList;  
  4.   
  5. public class Appliction {  
  6.   
  7.     public static void main(String[] args) {  
  8.         ArrayList<Command> commandList = new ArrayList<Command>();  
  9.         RequestPerson person = new RequestPerson();  
  10.         Command englishCommand = new PrintEnglishCommand(new PrintLetter());  
  11.         Command numberCommand = new PrintNumberCommand(new PrintNumber(10));  
  12.         commandList.add(englishCommand);  
  13.         commandList.add(numberCommand);  
  14.         Command macroCommand = new MacroCommand(commandList);  
  15.         person.setCommand(macroCommand);  
  16.         person.startExecuteCommand();  
  17.           
  18.           
  19.     }  
  20. }  


命令者模式的优点
1、在命令者模式中,请求者不直接与接受者互交,既请求者不包含接受者的引用,因此彻底消除了彼此之间的耦合。
2、命令者模式满足了软件的“开-闭原则”。如果增加新的具体命令和该命令的接受者,不必修改调用者的代码,调用者就可以直接使用新的命令对象。反之如果增加新的调用者,不必修改现有的具体命令和接受者。新增加的调用者就可以使用已有的具体命令
3、由于请求者的请求被封装到了具体命令中,那么就可以将具体命令保存到持久化媒介中,在需要的时候重新执行这个具体命令。因此使用命令者模式可以记录日志
4、使用命令者模式可以对请求者的请求进行排队,每个请求者各自对应一个具体命令,因此可以按一定的顺序执行这些命令。
适用命令者模式的场景
1、程序需要在不同的时刻指定,排列和执行请求
2、程序需要提供撤销操作
3、程序需要支持宏操作

 

 

分享到:
评论

相关推荐

    JAVA-设计模式-行为型模式-命令模式

    JAVA-设计模式-行为型模式-命令模式

    设计模式--命令模式java例子

    设计模式--命令模式java例子

    java设计模式-命令模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段...

    JAVA设计模式-原则和23种设计模式归纳总结

    本资源主要介绍了JAVA设计模式的原则和23种设计模式的总结。设计模式是软件设计中的一种解决方案,能够使软件系统更加灵活、可维护和可扩展。本资源首先介绍了设计模式的六大原则,包括单一责任原则、开闭原则、里氏...

    Java设计模式-图解-附代码.doc

    在软件工程中,设计模式是一种被广泛接受的解决特定设计问题的...因此,深入学习和理解Java设计模式对于任何Java开发者来说都是至关重要的。通过文档中的图解和代码示例,读者可以更好地理解和掌握这些模式的实际应用。

    java常用设计模式-命令模式

    Java 命令模式设计模式详解 命令模式(Command Pattern)是一种行为设计模式,它允许将请求封装为一个对象,从而使不同的请求可以使用不同的参数进行参数化,队列或日志请求,以及支持可撤销的操作。在 Java 中,...

    Java设计模式-

    Java设计模式是软件工程中的一种重要思想,它代表了在解决特定问题时的最佳实践。这些模式都是经过时间和经验验证的设计解决方案,可以提高代码的可读性、可维护性和复用性。Java设计模式主要分为三类:创建型模式、...

    Java设计模式-23种设计模式详解

    Java设计模式详解 Java设计模式是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。 设计模式的六大原则...

    清华大学出版 基于java程序语言的java设计模式课程 18-解释器模式(共25页).pptx

    本课程适合所有需要弥补JAVA设计模式的同学,课件内容制作精细,由浅入深,适合入门或进行知识回顾。 【完整课程列表】 基于java程序语言的设计java模式课程 01-设计模式概述(共36页).pptx 基于java程序语言的...

    java之设计模式--各种设计模式解析

    java 设计模式 单例模式 工厂模式 命令模式 模式解析 各种模式的最全面的解析 最朴实的话语

    2020版23种Java设计模式-图解-附代码.pdf

    Java设计模式是软件开发中的重要概念,它是一种在特定情境下解决问题的经验总结,可以提高代码的可重用性、可维护性和灵活性。本教程详细介绍了23种经典的Java设计模式,包括创建型、结构型和行为型模式。下面将对这...

    Java设计模式-图解-附代码

    1.3.2 命令模式 40 1.3.3 解释器模式 43 1.3.4 迭代器模式 45 1.3.5 中介者模式 49 1.3.6 备忘录模式 52 1.3.7 观察者模式 54 1.3.8 状态模式 58 1.3.9 策略模式 61 1.3.10 模板方法 63 1.3.11 访问者模式 65

    java设计模式-备忘录模式

    Java设计模式中的备忘录模式(Memento Pattern)是一种用于保存对象状态的模式,以便在未来某一时刻能够恢复到之前的状态。这种模式的核心在于在不违反对象封装性的前提下,捕获对象的内部状态并将其存储起来。备忘...

    java设计模式-期末整理.pdf

    命令模式是一种行为设计模式,它将一个请求封装为一个对象,以便于使用不同的请求、队列请求以及支持可撤销的操作。在命令模式中,接收者是执行特定任务的对象,而命令接口定义了执行这些任务的规范。具体命令类实现...

    设计模式6---命令模式,精美PPT

    该PPT用于公司内部分享设计模式6---命令模式之用,言简意赅,形象生动.故此分享,希望大家一起学习

    计算机后端-Java-图解java设计模式104 命令模式(4)-Jdbc.avi

    计算机后端-Java-图解java设计模式104 命令模式(4)-Jdbc.avi

    72-Java设计模式 命令模式1

    72-Java设计模式 命令模式1

    java设计模式

    目录: 前 言 第一部分 大旗不挥,谁敢冲锋——热身篇 第1章 单一职责原则 1.1 我是“牛”类,我可以担任多职吗 1.2 绝杀技,打破你的传统思维 1.3 我单纯,所以我快乐 1.4 最佳实践 ...附录:23个设计模式

    23种java设计模式.pdf

    " JAVA 设计模式概述" JAVA 设计模式是指在软件设计过程中,为了提高代码的可维护性、灵活性和可扩展性所使用的一些惯用解决方案。JAVA 设计模式可以分为三种:创建模式、结构模式和行为模式。 1. 创建模式 创建...

    设计模式(JAVA语言实现)--20种设计模式附带源码PPT模板.pptx

    18命令模式:定义命令接口、定义接受者、实现具体命令接口命令模式:定义命令接口、定义接受者、实现具体命令接口 设计模式(JAVA语言实现)--20种设计模式附带源码PPT模板全文共22页,当前为第19页。 19备忘录模式...

Global site tag (gtag.js) - Google Analytics