命令模式

1. 什么是命令模式

Command 模武也叫命令模式,是行为设计模式的一种。Command 模式通过被称为 Command 的类封装了对目标对象的调用行为以及调用参数。

2. 命令模式的应用场景

在面向对象的程序设计中,一个对象调用另一个对象,一般情况下的调用过程是:创建目标对象实例;设置调用参数;调用目标对象的方法。

但在有些情况下有必要使用一个专门的类对这种调用过程加以封装,我们把这种专门的类称作 command 类。

  • 整个调用过程比较繁杂,或者存在多处这种调用。这时,使用 Command 类对该调用加以封装,便于功能的再利用。
  • 调用前后需要对调用参数进行某些处理。
  • 调用前后需要进行某些额外处理,比如日志,缓存,记录历史操作等。

3. 命令模式的结构

24_命令模式 - 图1

4. 命令模式的角色与职责

  • Command:Command 抽象类。
  • ConcreteCommand:Command 的具体实现类。
  • Receiver:需要被调用的目标对象。
  • Invoker:通过 Invoker 执行 Command 对象。

5. 代码演示

5.1. 不使用命令模式

  1. public class Peddler {
  2. public void sellApple() {
  3. System.out.println("卖苹果");
  4. }
  5. public void sellBanana() {
  6. System.out.println("卖香蕉");
  7. }
  8. }
  1. Peddler peddler = new Peddler();
  2. peddler.sellApple();
  3. peddler.sellBanana();

5.2. Command

  1. public abstract class Command {
  2. private Peddler peddler;
  3. public Command(Peddler peddler) {
  4. this.peddler = peddler;
  5. }
  6. public Peddler getPeddler() {
  7. return peddler;
  8. }
  9. public void setPeddler(Peddler peddler) {
  10. this.peddler = peddler;
  11. }
  12. public abstract void sell();
  13. }
  1. public class AppleCommand extends Command {
  2. public AppleCommand(Peddler peddler) {
  3. super(peddler);
  4. }
  5. @Override
  6. public void sell() {
  7. this.getPeddler().sellApple();
  8. }
  9. }
  1. public class BananaCommand extends Command {
  2. public BananaCommand(Peddler peddler) {
  3. super(peddler);
  4. }
  5. @Override
  6. public void sell() {
  7. this.getPeddler().sellBanana();
  8. }
  9. }
  1. Peddler peddler = new Peddler();
  2. Command appleCommand = new AppleCommand(peddler);
  3. Command bananaCommand = new BananaCommand(peddler);
  4. appleCommand.sell();
  5. bananaCommand.sell();

5.3. Waiter

  1. public class Waiter {
  2. private Command command;
  3. public Waiter() {
  4. }
  5. public Command getCommand() {
  6. return command;
  7. }
  8. public void setCommand(Command command) {
  9. this.command = command;
  10. }
  11. public void sell() {
  12. this.command.sell();
  13. }
  14. }
  1. Peddler peddler = new Peddler();
  2. Command appleCommand = new AppleCommand(peddler);
  3. Command bananaCommand = new BananaCommand(peddler);
  4. Waiter waiter = new Waiter();
  5. waiter.setCommand(appleCommand);
  6. waiter.sell();
  7. waiter.setCommand(bananaCommand);
  8. waiter.sell();

5.4. 改进 Waiter

  1. public class Waiter {
  2. private final List<Command> commands;
  3. public Waiter() {
  4. commands = new ArrayList<>();
  5. }
  6. public void addOrder(Command command) {
  7. this.commands.add(command);
  8. }
  9. public void removeOrder(Command command) {
  10. this.commands.remove(command);
  11. }
  12. public void sell() {
  13. for (Command command : commands) {
  14. command.sell();
  15. }
  16. }
  17. }
  1. Peddler peddler = new Peddler();
  2. Command appleCommand = new AppleCommand(peddler);
  3. Command bananaCommand = new BananaCommand(peddler);
  4. Waiter waiter = new Waiter();
  5. waiter.addOrder(appleCommand);
  6. waiter.sell();
  7. System.out.println("==========");
  8. waiter.addOrder(bananaCommand);
  9. waiter.sell();
  10. System.out.println("==========");
  11. waiter.removeOrder(appleCommand);
  12. waiter.sell();
  1. 卖苹果
  2. ==========
  3. 卖苹果
  4. 卖香蕉
  5. ==========
  6. 卖香蕉