定义 将来自客户端的请求传入一个对象,从而使你可用不同的请求对客户进行参数化。用于“行为请求者”与“行为实现者”解耦,可实现二者之间的松耦合,以便适应变化。分离变化与不变的因素。
组成角色 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(); } }执行结果