命令模式是关于怎样处理一个对象请求另一个对象调用其方法完成某项任务的一种模式。
在命令模式中,当一个对象请求另一个对象调用其方法时,不和被请求的对象对象直接打交道,而是把这种请求封装到一个命令对象中,其封装手段是将请求封装在命令对象的一个方法中。命令模式的核心 就是使用命令对象来封装方法调用,即将请求者的请求‘接受者调用方法’封装到命令对象的一个方法中 。
命令模式中包括4种角色。
1、接受者(Receiver)接受者是一个类的实例,该实例负责执行与请求相关的操作。
2、命令(Command)接口,命令是一个接口,规定了用来封装请求的若干方法。
3、具体命令(ConcreteCommand):具体命令是实现了命令接口的实例,具体命令必须实现命令接口中的方法。
4、请求者(Invoker),请求者是一个包含Command接口变量的类的实例,请求者中的Command接口的变量可以存放任何具体命令的引用,请求者负责调用具体命令,让具体命令执行封装的请求。
下面看一个小例子:
首先看接受者:
public class Receriver {
public void say(){
System.out.println("接受者执行方法");
}
}
接受者中的say()方法是具体执行的方法,也就是请求者要调用的方法。下面看一下命令接口:
public interface Command {
public void execute();
}
然后看一下命令接口的实现类,该类中包括一个命令接受者,在实例化该命令时,为该命令传入一个命令接受者,用于执行具体操作。public class CommandImpl implements Command {
private Receriver rec;
public CommandImpl(Receriver rec){
this.rec = rec;
}
@Override
public void execute() {
rec.say();
}
}
然后再看命令请求者,该类中包括一个命令接口,当他 要执行某些操作时,只需要将具体命令传入即可。public class Invoker {
public Command command;
public void setCommand(Command command) {
this.command = command;
}
public void run(){
command.execute();
}
}
下面看一个测试类:
public class Test {
public static void main(String[] args) {
//创建接受者
Receriver rec = new Receriver();
//创建命令对象,并为命令对象传入接受对象
Command command = new CommandImpl(rec);
//创建请求者对象
Invoker invoker = new Invoker();
//将命令对象传入请求者对象中
invoker.setCommand(command);
invoker.run();
}
}
生活中典型的命令模式是用遥控控制电视机开关以及切换频道,下面看一下具体演示。在这个模式中电视相当于接受者,用于进行具体操作。
public class TV {
public void turnon(){
System.out.println("电视开机……");
}
public void turnoff(){
System.out.println("电视关机……");
}
public void changeChannel(int currentChannel){
System.out.println("当前频道"+currentChannel);
}
}
通过遥控器控制电视相当于向电视发送一条条命令,下面看一下命令接口以及执行相应命令的接口。public interface Command {
public void execute();
}
下面是开机命令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.turnon();
}
}
下面是切换频道命令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);
}
}
遥控器相当于请求者,向电视发送一个个命令。下面看一下控制类。public class Contorl {
private Command commandon,commandoff,commandchange;
public Contorl(Command commandon,Command commandoff,Command commandchange){
this.commandon = commandon;
this.commandoff = commandoff;
this.commandchange = commandchange;
}
public void turnOn(){
commandon.execute();
}
public void turnOff(){
commandoff.execute();
}
public void turnChange(){
commandchange.execute();
}
}
然后我们看一下测试类public class Test {
public static void main(String[] args) {
TV mytv = new TV();
//开机命令
Command on = new CommandOn(mytv);
//关机命令
Command off = new CommandOff(mytv);
//切换频道命令
Command change = new CommandChange(mytv, 5);
//创建控制对象
Contorl cont = new Contorl(on, off, change);
//开机操作
cont.turnOn();
//切换频道
cont.turnChange();
//关机操作
cont.turnOff();
}
}
命令模式实现了请求者和接受者之间操作的解耦合。