设计模式
命令模式(Command)

命令模式(Command)

将"请求"封闭成对象, 以便使用不同的请求,队列或者日志来参数化其他对象. 命令模式也支持可撤销的操作。

在 java 中的 newInstance / invoke 采用的就是命令模式, newInstance() 相当于调用其它类的构造函数来创建对象, invoke 则是相当于调用对象的方法. 因为它们控制的都是 其他类 / 或者 对象的特性

实现

设计一个遥控器,可以控制电灯开关。

public interface Command {
    void execute();
}
 
        
  
public class LightOnCommand implements Command {
    Light light;
 
    public LightOnCommand(Light light) {
        this.light = light;
    }
 
    @Override
    public void execute() {
        light.on();
    }
}
 
        
  
public class LightOffCommand implements Command {
    Light light;
 
    public LightOffCommand(Light light) {
        this.light = light;
    }
 
    @Override
    public void execute() {
        light.off();
    }
}
 
        
  
public class Light {
 
    public void on() {
        System.out.println("Light is on!");
    }
 
    public void off() {
        System.out.println("Light is off!");
    }
}
 
        
  
/**
 * 遥控器
 */
public class Invoker {
    private Command[] onCommands;
    private Command[] offCommands;
    private final int slotNum = 7;
 
    public Invoker() {
        this.onCommands = new Command[slotNum];
        this.offCommands = new Command[slotNum];
    }
 
    public void setOnCommand(Command command, int slot) {
        onCommands[slot] = command;
    }
 
    public void setOffCommand(Command command, int slot) {
        offCommands[slot] = command;
    }
 
    public void onButtonWasPushed(int slot) {
        onCommands[slot].execute();
    }
 
    public void offButtonWasPushed(int slot) {
        offCommands[slot].execute();
    }
}
 
        
  
public class Client {
    public static void main(String[] args) {
        Invoker invoker = new Invoker();
        Light light = new Light();
        Command lightOnCommand = new LightOnCommand(light);
        Command lightOffCommand = new LightOffCommand(light);
        invoker.setOnCommand(lightOnCommand, 0);
        invoker.setOffCommand(lightOffCommand, 0);
        invoker.onButtonWasPushed(0);
        invoker.offButtonWasPushed(0);
    }
}