模式概述:
它可将请求转换为一个包含与请求相关的所有信息的独立对象。 该转换让你能根据不同的请求将方法参数化、 延迟请求执行或将其放入队列中, 且能实现可撤销操作。
使用场景:
1.如果你需要通过操作来参数化对象, 可使用命令模式。
2.如果你想要将操作放入队列中、 操作的执行或者远程执行操作, 可使用命令模式。
3.如果你想要实现操作回滚功能, 可使用命令模式。
代码样例:
代码背景: 对文本编辑器的内容进行插入和删除一段文本等相关操作,通过命令模式来进行实现,并实现撤销功能。
/**
* 编辑器
*/
public class Editor {
private String text;//编辑器内容
private Stack<Command> hisCommands = new Stack<>();
public Editor(String text) {
this.text = text;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Stack<Command> getHisCommands() {
return hisCommands;
}
public void setHisCommands(Stack<Command> hisCommands) {
this.hisCommands = hisCommands;
}
//将客户端的请求封装成对象(命令对象);即把函数封装成对象,封装成对象之后,对象就可以存储下来,
//方便控制执行,从而可以实现队列执行、日志记录、撤销等功能
/**
* 向文本编辑器中插入内容
*/
public void insertSomeText(String insertText){
Command command = new InsertCommand(insertText);
command.doIt(this);
}
/**
* 删除文本编辑器内容的前2个字
*/
public void deleteSomeText(){
Command command = new DeleteCommand();
command.doIt(this);
}
/**
* 返回操作
*/
public void back(){
if(!hisCommands.isEmpty()){
hisCommands.pop().unDo(this);
}
}
/**
* 命令接口
*/
public interface Command {
void doIt(Editor editor);
void unDo(Editor editor);//根据实际的业务逻辑,实现doIt对应的返回操作
}
/**
* 插入命令
*/
public class InsertCommand implements Command{
private String insertText;
private String backText;
public InsertCommand(String insertText) {
this.insertText = insertText;
}
@Override
public void doIt(Editor editor) {
editor.setText(insertText+editor.getText());
this.backText = insertText;
editor.getHisCommands().push(this);
}
@Override
public void unDo(Editor editor) {
editor.setText(editor.getText().substring(backText.length()));
}
}
/**
* 删除命令
*/
public class DeleteCommand implements Command{
private String backText;
@Override
public void doIt(Editor editor) {
this.backText = editor.getText().substring(0,2);
editor.setText(editor.getText().substring(2));
editor.getHisCommands().push(this);
}
@Override
public void unDo(Editor editor) {
editor.setText(backText + editor.getText());
}
}
/**
* 测试命令模式
*/
public class TestCommand {
public static void main(String[] args) {
Editor editor = new Editor("abcd");
System.out.println("编辑器初始内容为:"+editor.getText());
editor.insertSomeText("456");
System.out.println("编辑器执行一次插入操作后:"+editor.getText());
editor.insertSomeText("123");
System.out.println("编辑器执行两次插入操作后:"+editor.getText());
editor.deleteSomeText();
System.out.println("编辑器执行一次删除操作后:"+editor.getText());
editor.back();
System.out.println("编辑器执行一次撤销后:"+editor.getText());
editor.back();
System.out.println("编辑器执行两次撤销后:"+editor.getText());
editor.back();
System.out.println("编辑器执行三次撤销后:"+editor.getText());
}
}
测试结果: