命令模式

PPG007 ... 2021-12-30 About 2 min

# 命令模式

# 定义

将一个请求封装为一个对象,从而使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。

# 角色

  • Receiver 接收者:干活的角色,命令传递到此处被执行。
  • Command 命令角色:需要执行的所有命令都在这里声明。
  • Invoker 调用者角色:接收到命令并执行命令。

# 示例

抽象命令类:可以在这里将各接收者直接作为成员变量。

public abstract class AbstractCommand {
    public abstract void execute();
}
1
2
3

抽象接收者类:

public abstract class AbstractReceiver {
    public abstract void process();
}
1
2
3

上述抽象类的实现类:

public class Command1 extends AbstractCommand{

    private final AbstractReceiver receiver;

    public Command1(AbstractReceiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void execute() {
        this.receiver.process();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
public class Command2 extends AbstractCommand{

    private final AbstractReceiver receiver;

    public Command2(AbstractReceiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void execute() {
        this.receiver.process();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
public class Receiver1 extends AbstractReceiver{
    @Override
    public void process() {
        System.out.println("买瓶水");
    }
}
1
2
3
4
5
6
public class Receiver2 extends AbstractReceiver{
    @Override
    public void process() {
        System.out.println("买块肉");
    }
}
1
2
3
4
5
6

Invoker 类:

public class Invoker {
    private AbstractCommand command;

    public void setCommand(AbstractCommand command) {
        this.command = command;
    }

    public void execute(){
        this.command.execute();
    }
}
1
2
3
4
5
6
7
8
9
10
11

启动类:

public class Client {
    public static void main(String[] args) {
        Invoker invoker = new Invoker();
        invoker.setCommand(new Command1(new Receiver1()));
        invoker.execute();
        invoker.setCommand(new Command2(new Receiver2()));
        invoker.execute();
    }
}
1
2
3
4
5
6
7
8
9

# 命令模式的优点

  • 类间解耦:调用者角色与接收者角色之间没有任何依赖关系。
  • 可扩展性:Command 子类可以非常容易的扩展,调用者 Invoker 与 Client 不产生严重的耦合。
  • 命令模式结合其他模式会更优秀:结合责任链模式实现命令族解析任务;结合模板方法模式,可以减少 Command 子类的膨胀问题。

# 命令模式的缺点

命令数量和 Command 子类数量一对一,容易出现类爆炸。

# 命令模式使用场景

认为是命令的地方都可以。

# 命令模式的扩展

# 增加需求

要增加一个命令的工作量,只要修改 execute 方法即可。

# 反悔问题

  1. 结合备忘录模式还原最后状态,该方法适合接收者为状态的变更情况,而不适合事件处理。
  2. 增加新命令,实现事件的回滚。
Last update: December 30, 2021 09:14
Contributors: PPG007