设计模式(一)——命令模式

1.描述

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

2.优点

·命令模式中,请求者不直接与接受者交互,即请求者不包含接受者的引用,彻底消除了彼此的耦合度。

·命令模式满足“开闭原则”。如果增加新的具体命令和该命令的接受者,不必修改调用者的代码,调用者就可以使用新的命令对象;反之,如果增加新的调用者,不必修改现有的具体命令和接受者,新增加的调用者就可以使用已有的具体命令。

·由于请求者的请求被封装到具体命令中,那么就可以将具体命令保存到持久化的媒介中,在需要时重新执行这个具体命令。因此,使用命令模式可以记录日志。

·使用命令模式可以对请求者的“请求”排队。每个请求都各自对应一个具体命令,因此可以按照一定顺序执行这些命令。

3.用途

·程序在不同的时刻指定、排列和执行请求。

·程序需要提供撤销操作。

·程序需要支持宏操作。

4.模式的使用

命令模式中有四种角色

·接受者(Receiver):接受者是一个类的示实例,该实例负责执行与请求相关的操作。

·命令(Command)接口:命令时一个接口,规定了用来封装“请求”的若干方法。

·具体命令(ConcreteCommand):具体命令是实现命令接口的类的实例。具体命令必须实现命令接口中的方法。

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

5.UML图

6.案例

要求:请求者请求只输出英文字母表,只输出俄文字母表,只输出1~N的偶数,或者任意组合以上请求的命令。

对于上述问题我们设计

两个接受者:

PrintLetter打印英文字母或俄文字母

PrintEvenNumber打印偶数

命令接口:

Command

三个具体命令以及一个宏命令:

PrintEnglishCommand(打印英文字母)

PrintRussianCommand(打印俄文字母)

PrintEvenNumberCommand(打印偶数)

MacroCommand(宏命令)

 代码:

  1 package 命令模式.test2;
  2 /**
  3  * 接受者,打印字母
  4  */
  5 public class PrintLetter {
  6     public void printEnglish(){
  7         for(char c = 'a'; c < 'z'; c++ )
  8             System.out.print(c + "	");
  9     }
 10     
 11     public void printRussian(){
 12         for(char c = 'а'; c < 'я'; c++ )
 13             System.out.print(c + "	");
 14     }
 15 }
 16 
 17 
 18 package 命令模式.test2;
 19 
 20 /**
 21  * 接受者,打印数字
 22  */
 23 public class PrintNumber {
 24     int n;
 25     PrintNumber(int n){
 26         this.n = n;
 27     }
 28     
 29     public void printEvenNmuber(){
 30         for(int i = 1; i <= n; i++)
 31             if(i % 2 ==0)
 32                 System.out.println(i + "	");
 33     }
 34 }
 35 
 36 
 37 package 命令模式.test2;
 38 
 39 /**
 40  * 命令接口
 41  */
 42 public interface Command {
 43     public abstract void execute();
 44 }
 45 
 46 
 47 package 命令模式.test2;
 48 
 49 /**
 50  * 打印英文字母具体命令
 51  */
 52 public class PrintEnglishCommand implements Command {
 53     PrintLetter letter;
 54     PrintEnglishCommand(PrintLetter letter){
 55         this.letter = letter;
 56     }
 57     public void execute() {
 58         letter.printEnglish();
 59     }
 60 
 61 }
 62 
 63 
 64 package 命令模式.test2;
 65 
 66 /**
 67  * 打印俄文字母具体命令
 68  */
 69 public class PrintRussianCommand implements Command {
 70     PrintLetter letter;
 71     public PrintRussianCommand(PrintLetter letter) {
 72         this.letter = letter;
 73     }
 74 
 75     public void execute() {
 76         letter.printRussian();
 77     }
 78 
 79 }
 80 
 81 
 82 package 命令模式.test2;
 83 
 84 /**
 85  * 打印偶数具体命令
 86  */
 87 public class PrintEvenNumberCommand implements Command {
 88     PrintNumber letter;
 89     public PrintEvenNumberCommand(PrintNumber letter) {
 90         this.letter = letter;
 91     }
 92     public void execute() {
 93         letter.printEvenNmuber();
 94     }
 95 
 96 }
 97 
 98 
 99 package 命令模式.test2;
100 
101 import java.util.ArrayList;
102 
103 /**
104  * 宏命令,具体命令
105  */
106 public class MacroCommand implements Command {
107     ArrayList<Command> commandList;
108     public MacroCommand(ArrayList<Command> commandList) {
109         this.commandList = commandList;
110     }
111 
112     public void execute() {
113         for(int i = 0; i < commandList.size(); i++)
114             commandList.get(i).execute();
115     }
116 
117 }
118 
119 
120 package 命令模式.test2;
121 
122 /**
123  * 请求者
124  */
125 public class Request {
126     Command command;
127     public void setCommand(Command command){
128         this.command = command;
129     }
130     
131     public void execute(){
132         command.execute();
133     }
134 }
135 
136 
137 package 命令模式.test2;
138 
139 import java.util.ArrayList;
140 
141 public class test {
142 
143 
144     public static void main(String[] args) {
145         ArrayList<Command> commandList = new ArrayList<Command>();
146         Request request = new Request(); //创建请求者
147         Command c1 = new PrintEnglishCommand(new PrintLetter());
148         Command c2 = new PrintRussianCommand(new PrintLetter());
149         Command c3 = new PrintEvenNumberCommand(new PrintNumber(20));
150         commandList.add(c1);
151         commandList.add(c2);
152         commandList.add(c3);
153         Command MacroCommand = new MacroCommand(commandList);
154         request.setCommand(MacroCommand);
155         request.execute();
156     }
157 
158 }
原文地址:https://www.cnblogs.com/cxy2016/p/7531627.html