Command:命令模式
先代码
package h.l.demo.command;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 用来声明执行操作的接口
*/
abstract class Command {
protected CommandReceiver commandReceiver;
protected String commandContent;
// 设置命令执行者
public Command(CommandReceiver commandReceiver) {
this.commandReceiver = commandReceiver;
}
// 设置命令内容
public void setCommandContent(String commandContent) {
this.commandContent = commandContent;
}
// 获取命令内容
public String getCommandContent() {
return this.commandContent;
}
abstract public void Execute();
}
/**
* 具体命令类
*/
class ConcreteCommand extends Command {
public ConcreteCommand(CommandReceiver commandReceiver) {
super(commandReceiver);
}
@Override
public void Execute() {
commandReceiver.Action();
}
}
/**
* 具体命令类2
*/
class ConcreteCommand2 extends Command {
public ConcreteCommand2(CommandReceiver commandReceiver) {
super(commandReceiver);
}
@Override
public void Execute() {
commandReceiver.Action2();
}
}
/**
* Invoker类,要求该命令执行这个请求,相当于命令发起人和命令接收人中间传递消息的那个人,承前启后,前接收命令,后下发命令道执行者那。
*/
class Invoker {
private List<Command> commands = new ArrayList<>();
public void addCommand(Command command) {
System.out.println("【添加命令】:" + "\t" + command.getCommandContent()
+ "\t" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
commands.add(command);
}
public void execute() {
System.out.println("【执行命令】:");
for (Command command : commands) {
command.Execute();
}
}
}
/**
* 命令接收者:里面有一系列执行的动作
*/
class CommandReceiver {
public void Action() {
System.out.println("【执行命令】" + "\t" + "买好可乐,给你");
}
public void Action2() {
System.out.println("【执行命令】" + "\t" + "买好薯片,给你");
}
}
测试类:
package h.l.demo.command;
/**
*
* @author: Is-Me-Hl
* @date: 2020年2月14日
* @Description: 测试
*/
public class TestMainEnter {
public static void main(String[] args) {
// 命令执行人
CommandReceiver commandReceiver = new CommandReceiver();
// 命令
Command command = new ConcreteCommand(commandReceiver);
command.setCommandContent("帮我买一个可乐,谢谢");
// 命令2
Command command2 = new ConcreteCommand2(commandReceiver);
command2.setCommandContent("帮我买一包薯片,谢谢");
// 命令中间人
Invoker invoker = new Invoker();
invoker.addCommand(command);
invoker.addCommand(command2);
// 执行命令
invoker.execute();
}
}
测试结果:
后分析
- 个人建议:写代码是件幸福的事,So,do it
命令模式,定义:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。命令模式的逻辑,就是将客户的请求封装为对象,这个对象我们在这里称之为命令,这些命令的属性中对应绑定了一个命令的执行者类。整个操作通过中间人也就是Invoker类进行操作,客户在Invoker这里下发请求,Invoker可以对请求进行过滤等操作,将结果通过命令实例中自带的命令执行者进行命令的操作。这就是命令模式的一个逻辑。
命令模式的作用:第一,它能较容易的设计一个命令队列;第二,在需要的情况下可以较容易地将命令计入日志;第三,允许接收请求的一方决定是否接收请求(上述代码的Invoker类就是做这样的事);第四,可以容易地实现对请求的撤销和重做(Invoker类);第五,由于加进新的具体命令不影响其他的类,因此增加新的具体命令类很容易。最关键的优点就是命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分隔开。
其他例子:参考自《大话设计模式》烤肉串引来的思考。客户通过服务员点餐,服务员下单到烤肉师傅。这一个过程可以使用命令模式展示。
注:以上文章仅是个人总结,若有不当之处,望不吝赐教