介绍:
命令模式将请求发送者和接受者进行解耦,在发送者和接收者之间引入命令对象,将发送者的请求封装在命令对象中,在通过命令对象来调用接受者的方法.命令模式用于处理对象之间的调用关系,使得这种调用对象更加灵活.
定义:
将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销操作.
主要角色:
抽象命令类:
抽象命令类一般是一个接口,在其中声明了用于执行请求的execute()等方法,通过这些方法可以调用请求接受者的相关操作
具体命令类:
具体命令类是抽象命令类的子类,实现了在抽象命令类中声明的方法,它对应具体的接受者对象,绑定接收者对象动作.在实现execute()方法时,将调用接收者对象相关造作Action()
调用者:
调用者即请求的发送者,又称为请求者,它通过命令对象来执行请求.一个调用者并不需要在设定其接受者,因此他只与抽象命令类之间存在关联关系,在程序运行时将具体调用命令对象的execute()方法,间接调用接受者相关操作
接受者:
接受者执行与请求相关操作,它具体实现对请求业务处理
客户类:
在客户需要创建发送者对象和具体命令类对象,在创建具体命令对象时指定其对应的接收者,发送者和接受者之间无直接关系,通过具体命令对象实现间接调用.
结构图:
案例:
为了用户使用方便,某系统提供了咦系列功能键.如功能键FuncitonButtion可以用于退出系统(SystemExitClass),也可以用于打开帮助界面(DisplayHelpClass).用于可以通过修改配置文件来改变功能键的用途
结构图
优点:
- 降低系统耦合度
- 新的命令可以很容易加入到系统中,因为增加新的具体命令类不受影响到其他类.因此增加新的具体命令类很容易.
- 可以比较容易的设计命令队列和宏命令(组合命令),可以将多个命令组合在一起批量执行,实现批量操作
缺点:
- 增加代码量,使用命令模式可能会导致某些系统有过多的具体命令类,因为针对每一个命令类都需要设计一个具体命令类,所以某些系统可能会需要大量的具体命令类.
- 增加开发工作量
代码
抽象命令类:
public interface CommandInterface {
void execute();
}
调用者:
public class FunctionButton {
private CommandInterface command;
public void setCommand(CommandInterface command) {
this.command = command;
}
public void click(){
command.execute();
}
}
接收者1:
public class SystemExitClass {
public void exit(){
System.out.println("正在执行退出窗口逻辑.....");
}
}
具体命令类1:
public class ExitCommand implements CommandInterface {
public SystemExitClass setObj = new SystemExitClass();
@Override
public void execute() {
setObj.exit();
}
}
接收者2:
public class DisplayHelpClass {
public void display(){
System.out.println("正在执行帮助窗口逻辑.....");
}
}
具体命令类2:
public class HelpCommand implements CommandInterface{
public DisplayHelpClass hcObj = new DisplayHelpClass();
@Override
public void execute() {
hcObj.display();
}
}
测试:
public static void main(String[] args) {
//调用者
FunctionButton functionButton = new FunctionButton();
//退出
CommandInterface exit = new ExitCommand();
functionButton.setCommand(exit);
functionButton.click();
//帮助
CommandInterface help = new HelpCommand();
functionButton.setCommand(help);
functionButton.click();
}
结果: