命令模式主要是用来将命令发出者和命令响应者解耦合。将命令抽象成为类,命令发出者直接去调用命令,由命令再去调用具体的响应者,使得发出者和接受者不直接交互。也有利于将一组命令设计成一个命令队列或者宏命令,直接去调用命令队列,命令会一个一个的接着执行。当我们有新的命令的时候,不必对已有的发出者或者接受者进行修改,直接添加一个命令即可。
比如有一个家用电器的接口,电器都有开关和调节亮度声音大小的命令,建立了两个具体的家用电器电灯和电视,并且将这些命令抽象出来。
interface Command{
void execute();
void undo();
}
//开关命令
class OpenCloseCommand implements Command{
private Electricity electricity;
public OpenCloseCommand(Electricity electricity) {
this.electricity = electricity;
}
public void execute() {
electricity.turnon();
}
public void undo() {
electricity.turnoff();
}
}
//加入调节亮度高低命令
class UpDownCommand implements Command{
private Electricity electricity;
public UpDownCommand(Electricity electricity) {
this.electricity = electricity;
}
public void execute() {
electricity.turnup();
}
public void undo() {
electricity.turndown();
}
}
interface Electricity{
void turnon();
void turnoff();
void turnup();
void turndown();
}
class Light implements Electricity{
public void turnon() {
System.out.println("电灯开了!");
}
public void turnoff() {
System.out.println("电灯关了!");
}
public void turnup() {
System.out.println("电灯亮了");
}
public void turndown() {
System.out.println("电灯暗了");
}
}
class TV implements Electricity{
public void turnon() {
System.out.println("电视开了!");
}
public void turnoff() {
System.out.println("电视关了!");
}
public void turnup() {
System.out.println("电视亮了");
}
public void turndown() {
System.out.println("电视暗了");
}
}
class Invoke{
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void executeCommand(){
command.execute();
}
public void undoCommand(){
command.undo();
}
}
public class CommandTest {
public static void main(String[] args) {
Invoke invoke = new Invoke();//命令发出者
Light light = new Light();//命令接受者
OpenCloseCommand openCloseCommand = new OpenCloseCommand(light);//命令
invoke.setCommand(openCloseCommand);
invoke.executeCommand();
invoke.undoCommand();
TV tv = new TV();//命令接受者
UpDownCommand upDownCommand = new UpDownCommand(tv);//命令
invoke.setCommand(upDownCommand);
invoke.executeCommand();
invoke.undoCommand();
}
}
可以看到后面加入的调节亮度高低的命令,并没有修改命令发出者和接受者的代码。