`命令模式:将一个请求封装为一个对象,从而使用户可以用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作.
在许多设计中,一些类的设计人员经常遇到这样的问题:需要通过一个对象请求另一个对象调用其方法以达到某种目的,前提是请求者不希望或无法直接
和被请求者打交道,在这种情况下可以使用命令模式.
命令模式是关于怎样处理一个对象请求另一个对象调用其方法完成某项任务的一种成熟的模式,这里称提出请求的对象为请求者,被请求的对象为接收者.
命令模式结构中包括四个角色:
接收者:接收者是一个类的实例,该实例负责执行与请求相关的操作.
命令:命令是一个接口,规定了用来封装请求的若干个方法,比如execute,undo等方法.
具体命令:具体命令是实现命令接口类的实例.具体命令必须实现接口中的方法,比如execute方法,使该方法封装一个请求.
请求者:请求者是一个包含Command接口变量的类的实例.请求者中的Command接口的变量可以存放任何具体命令的引用.请求者负责调用具体命令,
让具体命令执行那些封装了请求的方法,比如execute方法等.
应用场景一:
用户发起一个请求可以在硬盘建立目录,请求成功后,还可以撤销请求.
方法.因此,执行一个宏命令相当于执行了许多具体命令.
应用场景二:
用户发起一个请求可以输出26个英文字母,还可以发起一个请求输出1-26个数字,同时开可以发起一个请求不仅输出26个英文字母,还可以输出1-26个数字.
在许多设计中,一些类的设计人员经常遇到这样的问题:需要通过一个对象请求另一个对象调用其方法以达到某种目的,前提是请求者不希望或无法直接
和被请求者打交道,在这种情况下可以使用命令模式.
命令模式是关于怎样处理一个对象请求另一个对象调用其方法完成某项任务的一种成熟的模式,这里称提出请求的对象为请求者,被请求的对象为接收者.
命令模式结构中包括四个角色:
接收者:接收者是一个类的实例,该实例负责执行与请求相关的操作.
命令:命令是一个接口,规定了用来封装请求的若干个方法,比如execute,undo等方法.
具体命令:具体命令是实现命令接口类的实例.具体命令必须实现接口中的方法,比如execute方法,使该方法封装一个请求.
请求者:请求者是一个包含Command接口变量的类的实例.请求者中的Command接口的变量可以存放任何具体命令的引用.请求者负责调用具体命令,
让具体命令执行那些封装了请求的方法,比如execute方法等.
应用场景一:
用户发起一个请求可以在硬盘建立目录,请求成功后,还可以撤销请求.
1.接收者,直接看代码Receiver.
<span style="font-size:12px;">package com.ilucky.pattern.command.one;
import java.io.File;
/**
* @author IluckySi
* @date 20140620
*/
public class Receiver {
public void execute(String filePath) {
File file = new File(filePath);
file.mkdir();
System.out.println(filePath + "创建成功!");
}
public void undo(String filePath) {
File file = new File(filePath);
file.delete();
System.out.println(filePath + "删除成功!");
}
}</span>
2.命令,直接看代码Command.
<span style="font-size:12px;">package com.ilucky.pattern.command.one;
/**
* @author IluckySi
* @date 20140620
*/
public interface Command {
public abstract void execute(String filePath);
public abstract void undo();
}</span>
3.具体命令,直接看代码CommandOne.
<span style="font-size:12px;">package com.ilucky.pattern.command.one;
import java.util.ArrayList;
import java.util.List;
/**
* @author IluckySi
* @date 20140620
*/
public class CommandOne implements Command {
private Receiver receiver;
private List<String> filePaths;
public CommandOne(Receiver receiver) {
this.receiver = receiver;
filePaths = new ArrayList<String>();
}
public void execute(String filePath) {
receiver.execute(filePath);
filePaths.add(filePath);
}
public void undo() {
if(filePaths.size() > 0) {
int size = filePaths.size();
String filePath = filePaths.get(size -1);
receiver.undo(filePath);
filePaths.remove(size - 1);
} else {
System.out.println("没有需要撤销的操作!");
}
}
}</span>
4.请求者,直接看代码Invoker.
<span style="font-size:12px;">package com.ilucky.pattern.command.one;
/**
* @author IluckySi
* @date 20140620
*/
public class Invoker {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void execute(String filePath) {
command.execute(filePath);
}
public void undo() {
command.undo();
}
}</span>
5.最后看测试代码MainTest.
<span style="font-size:12px;">package com.ilucky.pattern.command.one;
/**
* @author IluckySi
* @date 20140620
*/
public class MainTest {
public static void main(String[] args) {
Receiver receiver = new Receiver();
Command commandOne = new CommandOne(receiver);
Invoker invoker = new Invoker();
invoker.setCommand(commandOne);
invoker.execute("E:/1");
invoker.undo();
invoker.execute("E:/2");
invoker.execute("E:/3");
invoker.undo();
}
}
/**
输出结果(在E盘只有一个文件夹2):
E:/1创建成功!
E:/1删除成功!
E:/2创建成功!
E:/3创建成功!
E:/3删除成功!
*/</span>
宏命令:宏命令是一个具体命令,只不过他包含了其他具体命令的应用,当一个宏命令执行execute方法的时候,将使所有其包含的其他具体命令执行execute方法.因此,执行一个宏命令相当于执行了许多具体命令.
应用场景二:
用户发起一个请求可以输出26个英文字母,还可以发起一个请求输出1-26个数字,同时开可以发起一个请求不仅输出26个英文字母,还可以输出1-26个数字.
1.接收者,直接看代码ReceiverOne和ReceiverTwo.
<span style="font-size:12px;">package com.ilucky.pattern.command.two;
/**
* @author IluckySi
* @date 20140621
*/
public class ReceiverOne {
public void execute() {
for(char i = 'a'; i <= 'z'; i++) {
System.out.print(i);
}
System.out.println();
}
}</span>
<span style="font-size:12px;"><pre name="code" class="java">package com.ilucky.pattern.command.two;
/**
* @author IluckySi
* @date 20140621
*/
public class ReceiverTwo {
public void execute() {
for(int i = 1 ; i <= 26; i++) {
System.out.print(i + "");
}
System.out.println();
}
}
</span>
2.命令,直接看代码Command.
<span style="font-size:12px;">package com.ilucky.pattern.command.two;
/**
* @author IluckySi
* @date 20140621
*/
public interface Command {
public abstract void execute();
}</span>
3.具体命令,直接看代码CommandOne,CommandTwo,和宏命令MacroCommand.
<span style="font-size:12px;">package com.ilucky.pattern.command.two;
/**
* @author IluckySi
* @date 20140621
*/
public class CommandOne implements Command {
<span style="white-space:pre"> </span>private ReceiverOne receiverOne;
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>public CommandOne (ReceiverOne receiverOne) {
<span style="white-space:pre"> </span>this.receiverOne = receiverOne;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>public void execute() {
<span style="white-space:pre"> </span>receiverOne.execute();
<span style="white-space:pre"> </span>}
}</span>
<span style="font-size:12px;"><pre name="code" class="java">package com.ilucky.pattern.command.two;
/**
* @author IluckySi
* @date 20140621
*/
public class CommandTwo implements Command {
private ReceiverTwo receiverTwo;
public CommandTwo(ReceiverTwo receiverTwo) {
this.receiverTwo = receiverTwo;
}
public void execute() {
receiverTwo.execute();
}
}
</span>
<span style="font-size:12px;"><pre name="code" class="java">package com.ilucky.pattern.command.two;
import java.util.List;
/**
* @author IluckySi
* @date 20140621
*/
public class MacroCommand implements Command {
private List<Command> commandList;
public MacroCommand(List<Command> commandList) {
this.commandList = commandList;
}
public void execute() {
for(int i = 0; i < commandList.size(); i++) {
Command command = commandList.get(i);
command.execute();
}
}
}
</span>
4.请求者,直接看代码Invoker.
<span style="font-size:12px;">package com.ilucky.pattern.command.two;
/**
* @author IluckySi
* @date 20140621
*/
public class Invoker {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void execute() {
command.execute();
}
}</span>
5.最后看测试代码MainTest.
<span style="font-size:12px;">package com.ilucky.pattern.command.two;
import java.util.ArrayList;
import java.util.List;
/**
* @author IluckySi
* @date 20140621
*/
public class MainTest {
public static void main(String[] args) {
Invoker invoker = new Invoker();
ReceiverOne receiverOne = new ReceiverOne();
CommandOne commandOne = new CommandOne(receiverOne);
invoker.setCommand(commandOne);
invoker.execute();
ReceiverTwo receiverTwo = new ReceiverTwo();
CommandTwo commandTwo = new CommandTwo(receiverTwo);
invoker.setCommand(commandTwo);
invoker.execute();
List<Command> list = new ArrayList<Command>();
list.add(commandOne);
list.add(commandTwo);
MacroCommand macroCommand = new MacroCommand(list);
invoker.setCommand(macroCommand);
invoker.execute();
}
}
/**
输出结果:
abcdefghijklmnopqrstuvwxyz1234567891011121314151617181920212223242526abcdefghijklmnopqrstuvwxyz1234567891011121314151617181920212223242526
*/</span>