23 命令模式

1 定义

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

2 优势

  1. 能较容易的设计一个命令队列。
  2. 在需要的情况下,可以较容易的将命令记入日志。
  3. 允许接受请求的一方决定是否要否决请求。
  4. 可以容易的实现对请求的撤销和重做。
  5. 由于加进具体命令类不影响其他的类,因此增加新的具体命令操作很容易。
  6. 最重要一点就是:命令模式把请求一个操作的对象和怎么执行一个操作的对象解耦。

3 UML图

在这里插入图片描述

4 例子

4.1 场景

饭店点餐问题。客人点餐是请求一个操作;客人修改点的菜单是对已有操作的修改;后厨根据客人下的单做菜,是执行一个操作;但客人并不需要和后厨直接打交道,而是通过服务员完成点餐、修改菜,在没有食材的情况下否决客人的请求操作。

在这里插入图片描述

4.3 code

Main

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

        kaoYangRouCommand kaoYangRouCommand1=new kaoYangRouCommand(cook);
        kaoYangRouCommand kaoYangRouCommand2=new kaoYangRouCommand(cook);
        kaoChiCommand kaoChiCommand=new kaoChiCommand(cook);
        waiter.setOrder(kaoYangRouCommand1);
        waiter.setOrder(kaoYangRouCommand2);
        waiter.setOrder(kaoChiCommand);

        waiter.cancelOrder(kaoYangRouCommand2);
        //通知厨师
        waiter.notifyCook();
    }
}

AbstractCommand

public abstract class AbstractCommand {
    protected Barbecuer receiver;

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

    abstract public void excute();
}

kaoYangRouCommand

public class kaoYangRouCommand extends AbstractCommand {

    public kaoYangRouCommand(Barbecuer receiver) {
        super(receiver);
    }

    @Override
    public void excute() {
        receiver.kaoYangRou();
    }
}

kaoChiCommand

public class kaoChiCommand extends AbstractCommand {

    public kaoChiCommand(Barbecuer receiver) {
        super(receiver);
    }

    @Override
    public void excute() {
        receiver.kaoChi();
    }
}

Barbecuer

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

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

Waiter

public class Waiter {
    //用一个list保存很多请求的引用
    List<AbstractCommand> list = new ArrayList<>();

    //接受请求
    public void setOrder(AbstractCommand command) {
        String str=command.getClass().getSimpleName();
        if(str.equals("kaoChiCommand")){
            System.out.println("没有烤翅了,请点别的烧烤");
        }else{
            list.add(command);
            System.out.println("增加订单,"+str+"时间:"+new Date().toString());
        }
    }

    //撤销请求
    public void cancelOrder(AbstractCommand command) {
        list.remove(command);
        String str=command.getClass().getSimpleName();
        System.out.println("取消订单,"+str+"时间:"+new Date().toString());
    }

    //通知后厨做菜
    public void notifyCook() {
        list.forEach(command -> command.excute());
    }
}

5 注意

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值