0x01:命令模式简介
在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个, 我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计。
命令模式:请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
UML类图如下:
主要角色分析如下:
0x02:命令模式的实现
public class Receiver {
public void action() {
System.out.println("命令执行了~~~");
}
}
public abstract class Command {
protected Receiver receiver;
public Command(Receiver receiver) {
this.receiver = receiver;
}
//执行命令的方法
abstract public void execute();
}
ConcreteCommand类:具体的Command,用于构造传递接收者,根据场景需求,具体的命令类也可能有多个
public class ConcreteCommand extends Command {
//构造传递接收者
public ConcreteCommand(Receiver receiver) {
super(receiver);
}
//必须实现一个命令
@Override
public void execute() {
receiver.action();
}
}
Invoker类:接收命令,并执行命令
public class Invoker {
private Command command;
//接收命令
public void setCommand(Command command) {
this.command = command;
}
//执行命令
public void executeCommand() {
command.execute();
}
}
命令模式测试代码:首先定义一个接收者,然后定义一个命令用于发送给接收者,最后再声明一个调用者,即可把命令交给调用者执行
public class Client {
public static void main(String[] args) {
//定义接收者
Receiver receiver = new Receiver();
//定义一个发送给接收者的命令
Command command = new ConcreteCommand(receiver);
//声明调用者
Invoker invoker = new Invoker();
//把命令交给调用者执行
invoker.setCommand(command);
//执行命令
invoker.executeCommand();
}
}
0x03:命令模式在JDK与开源框架中的运用
JDK中的Runnable接口,Runnable 相当于命令模式中的抽象命令角色(Command)。Runnabl 中的run()方法就当于execute()方法。
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
只要是实现了Runnable接口的类都被认为是一个线程,相当于命令模式中的具体命令角色(ConcreteCommand)
Thread就是调用者(Invoker),提供了start,join,interrupt等方法来控制“命令”也就是Runnable的执行。而Receiver则是让程序员可以自由与Runnale组合的抽象。
实际上调用线程的start()方法之后,就有资格去争抢CPU资源,而不需要编写获得CPU资源的逻辑。而线程抢到CPU资源后,就会执行run()方法中的内容,用Runnable接口把用户请求和CPU执行进行解耦。
Activiti是一款优秀开源软件,通过阅读源码,不但可以了解工作流引擎执行的原理,还可以增加个人的编码功力。Activiti所有执行过程都是采用命令模式进行执行。
喜欢,在看