20230427 23. 命令模式 - 烧烤点单

介绍

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

命令模式

  • Command类,用来声明执行操作的接口
  • ConcreteCommand类,将一个接收者对象绑定于一个动作,调用接收者相应的操作,以实现executeCommand
  • Invoker类,要求该命令执行这个请求
  • Receiver类,知道如何实施与执行一个与请求相关的操作,任何类都可能作为一个接收者

命令模式的优点:

  • 命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分割开
  • 它能较容易地设计一个命令队列;
  • 在需要的情况下,可以较容易地将命令记入日志;
  • 允许接收请求的一方决定是否要否决请求;
  • 可以容易地实现对请求的撤销和重做;
  • 由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易;

敏捷开发原则告诉我们,不要为代码添加基于猜测的、实际不需要的功能。如果不清楚一个系统是否需要命令模式,一般就不要着急去实现它,事实上,在需要的时候通过重构实现这个模式并不困难,只有在真正需要如撤销/恢复操作等功能时,把原来的代码重构为命令模式才有意义

代码示例

Receiver

public class Barbecuer {
    public void bakeMutton() {
        System.out.println("烤羊肉");
    }

    public void bakeChickenWing() {
        System.out.println("烤鸡翅");
    }
}

Command

public abstract class Command {
    protected Barbecuer receiver;

    public Command(Barbecuer receiver) {
        this.receiver = receiver;
    }

    public abstract void execCommand();
}

Command实现类

public class BakeChickenWingCommand extends Command {
    public BakeChickenWingCommand(Barbecuer receiver) {
        super(receiver);
    }

    @Override
    public void execCommand() {
        receiver.bakeChickenWing();
    }
}


public class BakeMuttonCommand extends Command{
    public BakeMuttonCommand(Barbecuer receiver) {
        super(receiver);
    }

    @Override
    public void execCommand() {
        receiver.bakeMutton();
    }
}

Invoker

public class Waiter {
    private List<Command> orders = new ArrayList<>();

    public void addOrder(Command command) {
        orders.add(command);
    }

    public void removeOrder(Command command) {
        orders.remove(command);
    }

    public void execCommand() {
        for (Command command : orders) {
            command.execCommand();
        }
    }
}

客户端

public class Test {
    public static void main(String[] args) {
        Barbecuer barbecuer = new Barbecuer();
        Waiter waiter = new Waiter();

        waiter.addOrder(new BakeMuttonCommand(barbecuer));
        waiter.addOrder(new BakeChickenWingCommand(barbecuer));

        waiter.execCommand();
    }
}
posted @ 2023-06-22 14:39  流星<。)#)))≦  阅读(3)  评论(0编辑  收藏  举报