设计模式(十五)———命令模式(Command Pattren):命令也是类

设计模式(十五)———命令模式(Command Pattren):命令也是类

Scroll Down

Intent

将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。

应用实例

  • struts 1 中的 action 核心控制器 ActionServlet 只有一个,相当于 Invoker,而模型层的类会随着不同的应用有不同的模型类,相当于具体的 Command

使用场景

认为是命令的地方都可以使用命令模式,

  • GUI 中每一个按钮都是一条命令。
  • 模拟 CMD。

优点

  • 降低了系统耦合度。
  • 新的命令可以很容易添加到系统中去。

缺点

  • 使用命令模式可能会导致某些系统有过多的具体命令类。

Class Diagram

image.png

Command(命令)

Command角色负责定义命令的接口(API

ConcreteCommand(具体的命令)

ConcreteCommand角色负责实现Command角色的接口(API

Receiver(接收者)

Receiver角色是Command角色执行命令时的对象,也可以称其为命令接收者。

Client(请求者)

Client角色负责生成ConcreteCommand角色并分Receiver角色。

Invoker(发动者)

Invoker角色是开始执行命令的角色,他会调用在Command角色中定义的接口(API

Implementation

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

image.png

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);
    }
}

输出结果

"Light is on!"
"Light is off!"