将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作
经典的命令模式包括4个角色:
Command:定义命令的统一接口
ConcreteCommand:Command接口的实现者,用来执行具体的命令,某些情况下可以直接用来充当Receiver。
Receiver:命令的实际执行者
Invoker:命令的请求者,是命令模式中最重要的角色。这个角色用来对各个命令进行控制。
1.命令模式的本质是对命令进行封装,将发出命令的责任和执行命令的责任分割开。
2.每一个命令都是一个操作:请求的一方发出请求,要求执行一个操作;接收的一方收到请求,并执行操作。
3.命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否被执行、何时被执行,以及是怎么被执行的。
4.命令模式使请求本身成为一个对象,这个对象和其他对象一样可以被存储和传递。
5.命令模式的关键在于引入了抽象命令接口,且发送者针对抽象命令接口编程,只有实现了抽象命令接口的具体命令才能与接收者相关联。
public static void main(String[] args) {
// 命令接受者Receiver
Tv myTv = new Tv();
//开机命令ConcreteCommand
Command on = new CommandOn(myTv);
//关机命令ConcreteCommand
Command off = new CommandOff(myTv);
//频道切换命令ConcreteCommand
Command channel = new CommandChange(myTv, 3);
//通过遥控器控制命令
Control control = new Control();
control.setOrder(on);
control.OK();
control.setOrder(off);
control.OK();
control.setOrder(channel);
control.OK();
}
/**
* 模拟对电视机的操作 有开机,关机,换台命令
* 执行命令的接口
* @author guk
*
*/
public interface Command {
void execute();
}
public class Control {
private List<Command> orderList = new ArrayList<>();
public void setOrder(Command command) {
orderList.add(command);
}
private void cancelOrder() {
orderList.clear();
}
public void OK() {
for(Command command : orderList) {
command.execute();
}
cancelOrder();
}
}
/**
* 命令接受者Receiver
* @author guk
*
*/
public class Tv {
public int currentChannel;
public void turnOn() {
System.out.println("The television is on");
}
public void turnOff() {
System.out.println("The television is off.");
}
public void changeChannel(int channel) {
this.currentChannel = channel;
System.out.println("Now TV channel is " + channel);
}
}
public class CommandOn implements Command {
private Tv tv;
public CommandOn(Tv tv) {
this.tv = tv;
}
@Override
public void execute() {
tv.turnOn();
}
}
public class CommandOff implements Command {
private Tv tv;
public CommandOff(Tv tv) {
this.tv = tv;
}
@Override
public void execute() {
tv.turnOff();
}
}
public class CommandChange implements Command {
private Tv tv;
private int channel;
public CommandChange(Tv tv, int channel) {
this.tv = tv;
this.channel = channel;
}
@Override
public void execute() {
tv.changeChannel(channel);
}
}