1.定义:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
2.UML类图:
3.简单代码实现:
//用来声明执行操作的接口,包含一个接收者引用
package com.guo.commandPattern;
public abstract class Command {
protected Receiver receiver;
public Command(Receiver receiver) {
super();
this.receiver = receiver;
}
public abstract void execute();
}
//将一个接收者对象绑定于动作,通过调用接收者的方法来执行动作
package com.guo.commandPattern;
public class ConcreteCommand extends Command {
public ConcreteCommand(Receiver receiver) {
super(receiver);
}
@Override
public void execute() {
receiver.action();
}
}
//要求该命令执行这个请求
package com.guo.commandPattern;
public class Invoker {
private Command command;
public void setCommand(Command command){
this.command = command;
}
public void executeCommand(){
command.execute();
}
}
//知道如何执行一个与请求相关的操作,任何类都可以作为一个接收者
package com.guo.commandPattern;
public class Receiver {
public void action(){
System.out.println("执行请求!!!");
}
}
//客户端代码:创建一个具体的命令对象并给它设置接收者,同时通过调用者执行动作
package com.guo.commandPattern;
public class CommandClient {
public static void main(String[] args) {
Receiver receiver = new Receiver();
Command command = new ConcreteCommand(receiver);
Invoker invoker = new Invoker();
invoker.setCommand(command);
invoker.executeCommand();
}
}
4.Example的UML类图:
5.Example的代码实现:
package com.guo.commandPattern.example;
public abstract class Command {
protected Barbecuer receiver;
public Command(Barbecuer receiver) {
super();
this.receiver = receiver;
}
public abstract void executeCommand();
}
package com.guo.commandPattern.example;
public class BakeMuttonCommand extends Command {
public BakeMuttonCommand(Barbecuer receiver) {
super(receiver);
}
@Override
public void executeCommand() {
receiver.bakeMutton();
}
}
package com.guo.commandPattern.example;
public class BakeChickenWingCommand extends Command {
public BakeChickenWingCommand(Barbecuer receiver) {
super(receiver);
}
@Override
public void executeCommand() {
receiver.bakeChickenWing();
}
}
package com.guo.commandPattern.example;
public class Barbecuer {
public void bakeMutton(){
System.out.println("烤羊肉串!");
}
public void bakeChickenWing(){
System.out.println("烤鸡翅!");
}
}
package com.guo.commandPattern.example;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class Waiter {
private List<Command> orders = new ArrayList<>();
public void setOrders(Command command){
if ("BakeChickenWingCommand".equals( command.getClass().getSimpleName() )) {
System.out.println("服务员:鸡翅没有了,请点别的烧烤。");
} else {
orders.add(command);
System.out.println("增加订单:" + command.getClass().getSimpleName()
+ " ,下单时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
}
}
public void cancelOrders(Command command){
orders.remove(command);
}
public void notifyBarbecuer(){
for (Command command : orders) {
command.executeCommand();
}
}
}
public static void main(String[] args) {
Barbecuer barbecuer = new Barbecuer();
Command bakeMuttonCommand1 = new BakeMuttonCommand(barbecuer);
Command bakeMuttonCommand2 = new BakeMuttonCommand(barbecuer);
Command chickenWingCommand = new BakeChickenWingCommand(barbecuer);
Waiter waiter = new Waiter();
waiter.setOrders(bakeMuttonCommand1);
waiter.setOrders(bakeMuttonCommand2);
waiter.setOrders(chickenWingCommand);
waiter.notifyBarbecuer();
}
6.优点:第一,它能较容易的设计一个命令队列;第二,在需要的情况下,可以较容易地将命令计入日志;第三,允许接受请求的一方决定是否要否决请求;第四,可以容易地实现对请求的撤销和重做;第五,由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易。另外,命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分隔开。