定义
将来自客户端的请求传入一个对象,从而使你可用不同的请求对客户进行参数化。用于“行为请求者”与“行为实现者”解耦,可实现二者之间的松耦合,以便适应变化。分离变化与不变的因素。
组成角色
1、Command
定义命令的接口,声明执行的方法。
2、ConcreteCommand
命令接口实现对象,是“虚”的实现;通常会持有接收者,并调用接收者的功能来完成命令要执行的操作。
3、Receiver
接收者,真正执行命令的对象。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能。
4、Invoker
要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口。
5、Client
创建具体的命令对象,并且设置命令对象的接收者。注意这个不是我们常规意义上的客户端,而是在组装命令对象和接收者,或许,把这个Client称为装配者会更好理解,因为真正使用命令的客户端是从Invoker来触发执行。
优缺点
优点:
1、 类间解耦
调用者角色与接收者角色之间没有任何依赖关系,调用者实现功能时只需调用Command抽象类的execute方法就可以,不需要了解到底是哪个接收者执行。
2、 可扩展性
Command的子类可以非常容易地扩展,而调用者Invoker和高层次的模块Client不产生严重的代码耦合。
缺点:
如果有N个命令,Command的子类就是N个,这个类膨胀的非常大,需要在项目中慎重考虑使用。
代码示例
定义命令的接口,声明执行的方法。
/**
* 执行命令的接口
* @author lu
* @since 1.0, 2020年7月4日
*/
public interface Command {
void exeute();
}
命令接口实现对象
/**
* 开机命令
* @author lu
* @since 1.0, 2020年7月4日
*/
public class CommandOn implements Command {
private Tv myTv;
public CommandOn(Tv tv){
myTv = tv;
}
@Override
public void exeute() {
myTv.turnOn();
}
}
/**
* 关机命令
* @author lu
* @since 1.0, 2020年7月4日
*/
public class CommandOff implements Command{
private Tv myTv;
public CommandOff(Tv tv){
myTv = tv;
}
@Override
public void exeute() {
myTv.turnOff();
}
}
/**
* 切换频道
* @author lu
* @since 1.0, 2020年7月4日
*/
public class CommandChange implements Command{
private Tv myTv;
private int channel;
public CommandChange(Tv tv,int channel){
myTv = tv;
this.channel = channel;
}
@Override
public void exeute() {
myTv.changeChannel(channel);
}
}
接收者,真正执行命令的对象。
/**
* 命令接收者Receiver
* @author lu
* @since 1.0, 2020年7月4日
*/
public class Tv {
public int currentChannel = 0;
public void turnOn(){
System.out.println("on:开的状态");
}
public void turnOff(){
System.out.println("off:关的状态");
}
public void changeChannel(int channel){
this.currentChannel = channel;
System.out.println("切换频道");
}
}
/**
* 遥控器
* @author lu
* @since 1.0, 2020年7月4日
*/
public class Control {
private Command onCommand,offCommand,changeCommand;
public Control(Command on,Command off,Command channel){
onCommand = on;
offCommand = off;
changeCommand = channel;
}
public void turnOn(){
onCommand.exeute();
}
public void turnOff(){
offCommand.exeute();
}
public void changeChannel(){
changeCommand.exeute();
}
}
/**
* 测试客户端
* @author lu
* @since 1.0, 2020年7月4日
*/
public class Client {
public static void main(String[] args) {
//命令 接收者
Tv myTv = new Tv();
//开机命令
CommandOn on = new CommandOn(myTv);
//关机命令
CommandOff off = new CommandOff(myTv);
//频道切换命令
CommandChange channel = new CommandChange(myTv,2);
//命令控制对象
Control control = new Control(on,off,channel);
//开机
control.turnOn();
//切换频道
control.changeChannel();
//关机
control.turnOff();
}
}
执行结果