设计模式(六)几段代码搞明白命令模式

  • 一文带你搞懂Java动态代理
  • 几分钟带你搞懂策略模式
  • 几分钟带你搞懂观察者模式
  • 一文彻底搞明白工厂和抽象工厂
  • 一文搞明白装饰者模式
  • 最全单例模式
  • 几段代码搞明白命令模式
  • 几段代码搞明白适配器模式
  • 一看就懂的外观模式
  • 一看就懂的模版方法模式
  • 几段代码搞懂迭代器模式
  • 一文搞懂明白状态模式

关于命令模式的定义,我就直接引用Head First了:命令模式将“请求”封装成对象,以便使用不同的请求。目的是将发起请求的对象和具体执行处理请求的对象完全解耦,并能灵活扩展具有不同操作的接收者对象。

命令模式

假如我们有一个遥控器可以控制不同硬件设备。如:通过一个按钮来控制智能灯的“开灯”,“关灯”。
设计模式(六)几段代码搞明白命令模式_第1张图片

这是智能灯的接口。当前只有两个方法,即开灯和关灯操作。

public class Light {
    public void on() {
        System.out.println("开灯");
    }
    public void off() {
        System.out.println("关灯");
    }
}

这是命令对象接口。通过调用命令对象的 execute() 方法,即可执行具体的接收者操作。

public interface Command {
    public void execute();
}

这是智能灯命令对象,是 Command 的实现类。我们将开灯的请求进行了封装,这个请求即调用“接收者开灯”这个操作。

public class LightOnCommand implements Command {
    private Light mLight;
    public LightOnCommand(Light light) {
        mLight = light;
    }
    @Override public void execute() {
        mLight.on();
    }
}

同样我们将“接收者关灯”这个请求,也封装成对象。

public class LightOffCommand implements Command {
    private Light mLight;
    public LightOnCommand(Light light) {
        mLight = light;
    }
    @Override public void execute() {
        mLight.off();
    }
}

假如我们有一个遥控器类,可以通过按钮控制智能灯的“开灯”和“闭灯”,代码见下:

public class Control {
    private Command mComBtn;
    public void setCommand(Command comBtn) {
        mComBtn = comBtn;
    }
    public void btnWasPressed() {
        mComBtn.execute();
    }
}

发出请求的对象(Control 类)与接收者(Light)是完全解耦的,两者是通过命令对象(Command实现类)沟通的,命令对象封装了接收者的一组动作,当然可多组,这里即“打开智能灯”,“关闭智能灯”的操作。调用者 Control 可直接通过 execute 方法,可动态指定执行特定接收者命令。 我们来进行下测试:

public class Test {
    public static void main(String[] ags) {
        Control control = new Control();
        Light light = new Light();
        // 开灯
        control.setCommand(new LightOnCommand(light));
        control.execute();
        // 关灯
        control.setCommand(new LightOffCommand(light));
        control.execute();
    }
}

也许你会有疑惑,为何不实现一个智能硬件接口 Ihardware呢?让我们的Control 直接持有Ihardware呢,针对上面这个类当然可以的。但是如果我们需要再扩展一个智能空调类 AirCon,甚至更多硬件类呢?

public class AirCon {
    public void on();
    public void off();
    // 独有的调节温度
    public void adjustTemperature();
}

这个时候再想想命令模式,是不是更有优势呢?我们只需要将调节温度这个请求封装成对象,而完全不必更改 Control 对象。当然这也会和装饰者模式一样,会造成大量的小类,所以具体的选型需要全方位衡量判断。

你可能感兴趣的:(模式架构)