书上的原句:
命令模式:将一个请求封装为一个对象从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。
拿一个烧烤店的例子来说:
//客户端
public class Main {
public static void main(String[] args) {
Barbecuer barbecuer = new Barbecuer();
barbecuer.bakeChickenWing();
barbecuer.bakeMutton();
barbecuer.bakeMutton();
barbecuer.bakeChickenWing();
barbecuer.bakeMutton();
}
}
//烧烤的厨师
class Barbecuer {
public void bakeMutton(){
System.out.println("bakeMutton");
}
public void bakeChickenWing(){
System.out.println("bakeChickenWing");
}
}
上面可以看成顾客直接面对厨师,客户点一个菜,厨师就做一个菜,中途不能撤销。
使用命令模式后是这样的:
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
Barbecuer barbecuer = new Barbecuer();
Command command_1 = new ChickenWingCommand(barbecuer);
Command command_2 = new MuttonCommand(barbecuer);
Command command_3 = new ChickenWingCommand(barbecuer);
Waiter waiter = new Waiter();
waiter.addCommand(command_1);
waiter.addCommand(command_2);
waiter.addCommand(command_3);
//撤销一个菜(命令)
waiter.removeCommand(command_3);
//执行之前的菜单(命令集合)
waiter.do_notify();
}
}
//厨师
class Barbecuer {
public void bakeMutton(){
System.out.println("bakeMutton");
}
public void bakeChickenWing(){
System.out.println("bakeChickenWing");
}
}
//抽象命令
abstract class Command {
protected Barbecuer barbecuer;
public Command(Barbecuer barbecuer) {
this.barbecuer = barbecuer;
}
abstract void excCommand();
}
//烤羊肉的命令
class MuttonCommand extends Command {
public MuttonCommand(Barbecuer barbecuer) {
super(barbecuer);
}
@Override
void excCommand() {
barbecuer.bakeMutton();
}
}
//烤鸡翅命令
class ChickenWingCommand extends Command {
public ChickenWingCommand(Barbecuer barbecuer) {
super(barbecuer);
}
@Override
void excCommand() {
barbecuer.bakeChickenWing();
}
}
//服务员,用来记下客户点的菜,可以进行撤销操作
class Waiter{
private List<Command> commands = new ArrayList<>();
public void addCommand(Command command) {
this.commands.add(command);
}
public void removeCommand(Command command) {
this.commands.remove(command);
}
public void do_notify(){
for (Command command: commands) {
command.excCommand();
}
}
}
我们增加了命令类Command和它的具体命令类,还有一个Waiter服务员类,用来管理命令集合,这样顾客就只用和服务员打交道,而不用直接面对厨师,而且在命令提交前可以撤销