一、什么是命令模式?
命令模式将一个请求封装成一个对象,从而可以对不同的请求作出不同的回应。比如在公司,老板发出一条命令给小组leader,leader又派发给手下的组员。这个过程使老板、命令、leader和执行命令的组员几者解耦,任何一方都不用去依赖其他人,只需要做好自己分内的事情,老板只需要结果,他并不需要知道到底哪个员工完成了命令,员工也不需要知道这个命令是谁发布的,只需要按照leader的吩咐去完成即可。
命令模式涉及到以下几个角色:
1. 抽象命令角色:定义了具体命令需要实现的抽象方法或接口
2. 具体命令角色:指定了具体命令的执行
3. 请求者(Invoker)角色:调用命令对象执行请求
4. 接收者(Receiver)角色:真正执行请求的对象
5. 客户端角色:创建具体命令对象并可以设定接收者
举一个简单易懂的例子——看电视:电视有三种功能(简单来看)——打开,调台,关闭。当用户要对电视进行操作时,一般是通过遥控器来操作:用户要打开电视,首先按住遥控器的开机按键,遥控器发指令给电视,电视再打开。这个例子在命令模式中,用户就是客户端角色,遥控器是请求者角色,开机,调台等功能就是具体的命令,而电视机就是接收者。
二、命令模式框图
三、命令模式的具体实现代码
3.1 Command——抽象命令接口
package designpatterns.command;
/**
* Created by Olive on 2017/12/26.
*/
public interface Command {
void execute();
}
3.2 CommandOn、CommandOff、CommandChangeChanneln——具体的命令,分别代表打开、关闭和调台三个具体操作,实现了Command接口
package designpatterns.command;
/**
* Created by Olive on 2017/12/26.
*/
public class CommandOn implements Command{
private TV tv;
public CommandOn(TV tv){
this.tv = tv;
}
public void execute() {
tv.turnOn();
}
}
public class CommandOff implements Command{
private TV tv;
public CommandOff(TV tv){
this.tv = tv;
}
public void execute() {
tv.turnOn();
}
}
public class CommandChangeChannel implements Command{
private TV tv;
private int channel;
public CommandChangeChannel(TV tv, int channel){
this.tv = tv;
this.channel = channel;
}
public void execute() {
tv.changeChannel(this.channel);
}
}
3.3 TV——电视机,也就是接收者
package designpatterns.command;
/**
* Created by Olive on 2017/12/26.
*/
public class TV {
private int channel = 0;
public void turnOn(){
System.out.println("Turn on the TV");
}
public void turnOff(){
System.out.println("Turn off the TV");
}
public void changeChannel(int channel){
this.channel = channel;
System.out.println("Channel is: " + this.channel);
}
}
3.4 RemoteControl——遥控器,调用者
package designpatterns.command;
/**
* Created by Olive on 2017/12/26.
*/
public class RemoteControl {
private Command onTV, offTV, changeChannel;
public RemoteControl(Command OnTV, Command OffTV, Command ChangeChannel){
this.onTV = OnTV;
this.offTV = OffTV;
this.changeChannel = ChangeChannel;
}
public void turnOn(){
onTV.execute();
}
public void turnOff(){
offTV.execute();
}
public void changeChannel(){
changeChannel.execute();
}
}
3.5 Client——客户端
package designpatterns.command;
/**
* Created by Olive on 2017/12/26.
*/
public class Client {
public static void main(String[] args){
TV tv = new TV();
// 建立开电视,换台以及关电视命令
CommandOn commandOn = new CommandOn(tv);
CommandChangeChannel commandChange = new CommandChangeChannel(tv, 3);
CommandOff commandOff = new CommandOff(tv);
// 创建遥控器,即调用者对象
RemoteControl remoteControl = new RemoteControl(commandOn, commandOff,commandChange);
// 发出命令
remoteControl.turnOn();
remoteControl.changeChannel();
remoteControl.turnOff();
}
}
3.6 结果
Turn on the TV
Channel is: 3
Turn on the TV
Process finished with exit code 0