命令模式介绍
命令模式是指,将需要执行的命令封装成一个对象,对象在程序中可以被任意传递,而不需要关心命令是被谁执行的,通过这个命令对象实现了命令请求和命令接收的解耦。打个比方说,去餐厅吃饭,服务员给了一个菜单,客人选择好菜品,服务员将菜单传递给厨师就好,客人并不知道是哪位厨师为自己烹饪食物,在这个例子中,菜单就是被封装的命令对象,服务员是命令的调度者,而厨师就是最终执行命令的人。
上面的餐厅点餐示例中,菜单就表示可以被自由传递的命令对象,它由服务员也就是命令调度者负责调度命令的执行,具体的命令执行者为厨师。
代码示例
现在有一个需要,要实现通过命令获取当前的国家和时间信息。想要实现这个需求,首先要创建一个具体的获取国家和时间的命令执行者类,然后创建两个命令对象,一个表示获取国家信息命令,另一个表示获取时间信息命令,最后创建一个调度者类,定义如何执行这两条命令。
创建具体的命令执行类
/**
* 执行命令的对象
*/
public class Receiver {
/**
* 当前日期
*/
public void date() {
System.out.println(new Date());
}
/**
* 当前国家
*/
public void country() {
System.out.println("中国");
}
}
执行类包含获取当前的国家和时间的两个方法。
创建抽象命令类
/**
* 命令接口
*/
public interface Command {
/**
* 执行命令抽象方法
*/
void execute();
}
抽象命令类定义了用来调用执行类中命令的方法
创建具体的命令类
/**
* 具体命令类-当前日期
*/
public class CommandDate implements Command{
private Receiver custom;
public CommandDate(Receiver custom) {
this.custom = custom;
}
@Override
public void execute() {
custom.date();
}
}
/**
* 具体命令类-当前国家
*/
public class CommandCountry implements Command{
private Receiver custom;
public CommandCountry(Receiver custom) {
this.custom = custom;
}
@Override
public void execute() {
custom.country();
}
}
上面两个类中包含了命令执行对象,并在各自的execute
方法中调用了执行对象的具体命令。
创建一个命令调度者
/**
* 命令调度
*/
public class Call {
private List<Command> list = new ArrayList<>();
/**
* 获取命令
* @param command 命令对象
*/
public void takeCommand(Command command) {
list.add(command);
}
/**
* 执行命令
* @param command
*/
public void implCommand() {
list.forEach(c -> {
c.execute();
});
}
}
命令调度类中包含命令对象的集合,用来存储多个命令对象,takeCommand()
方法用来添加新的命令对象到集合中,implCommand()
方法则是实现依次执行命令集合中所有的命令。拿餐厅点餐例子来说,takeCommand()
就像是客户在点菜,implCommand()
方法就像是厨师根据菜单依次烹饪食物。当然这里的代码案例实现的是依次执行获取时间和国家的两个命令。
测试命令模式
public class test_01 {
public static void main(String[] args) throws InterruptedException {
//创建命令执行对象
Receiver receiver = new Receiver();
//创建具体命令对象
Command date = new CommandDate(receiver);
Command country = new CommandCountry(receiver);
//创建命令调度对象
Call call = new Call();
//添加对象到命令列表
call.takeCommand(date);
call.takeCommand(country);
//依次执行命令列表中的命令
call.implCommand();
}
}
第一步,创建具体的命令执行对象。第二步,创建具体的命令对象。第三步,创建命令调度对象,将命令添加到命令列表并依次执行所有命令。
运行结果:
总结
命令模式实现了通过命令对象将命令的请求和执行解耦,命令对象可以自由的在程序中被传递,命令请求者不需要知道命令最终被谁处理,实现了将命令以参数的形式进行传递。并且在命令模式中,因为命令是独立存在的,所以在需要添加新的命令时,很容易扩展,提高了程序的灵活性。