设计模式之命令模式

命令模式

  • 概念
  • 类图
  • 代码实例

概念

将一个请求(命令)封装成一个对象,从而具有不同请求(命令)供客户度选择,对请求排队、记录以及支持可重做和撤销操作

好处:

1、能很容易设计一个命令队列
2、很容易记录每个命令的日志
3、可以实现命令重做和撤销
4、在不修改已有类情况下,很容易添加新命令类
5、将请求一个操作对象和具体执行该操作的对象分离开,也就是下面讲到的将客户和烧烤人分开之间通过Waiter中间人来进行委派客户请求

并不是去猜测这些代码需要用命令模式来重构,但是敏捷开发原则告诉我们,一切需要基于现实,不要有任何猜测,那么后面需要有命令重做和撤销以及记录等功能时,再进行重构为命令模式才有意义。

类图

在这里插入图片描述

Waiter:服务员类(Invoker)

Command:命令抽象类(Command)

Barbecuer:命令接受者(Receiver)

BakeBeefCommand:烤牛肉命令(ConcreteCommand1)

BakeChickenWindCommand:烤鸡翅命令

BakeMuttonCommand:烤羊肉串命令

Client:测试类

代码实例

Waiter:服务员类


/**
 * @author duanyimiao
 * @create 2018-11-08 6:27 AM
 * @description 服务员类,是客户和烧烤师傅之间中间类,降低客户和烧烤师傅之间耦合。也就是服务员代替客户发出命令
 * <p>
 * 1、(根据依赖倒置原则)服务员类需依赖一种抽象命令类,具体命令可以看做成菜单例如烤茄子、烤羊肉串等而具体命令中的操作需要委托烧烤人来执行
 * <p>
 * 2、记录客户发起的命令,也就是记录下单记录
 * <p>
 * 3、服务员批量将菜单交给烧烤师傅制作
 * <p>
 * 4、判断客户该命令请求是否能得到执行
 * <p>
 * 5、支持对未制作的菜进行撤销
 **/
public class Waiter {

    private List<Command> commands = new ArrayList<>();

    //用于接受命令
    public void setOrder(Command command) {
        //假如鸡翅没有了
        if (command instanceof BakeChickenWindCommand) {
            System.out.println("sorry chicken wind was sold out");
            return;
        }
        commands.add(command);
        System.out.println("增加订单 " + command + " 时间 " + new Date());
    }

    public void cancelOrder(Command command) {
        commands.remove(command);
        System.out.println("取消订单 " + command + " 时间 " + new Date());
    }

    public void notifyToMake() {
        for (Command command : commands) {
            command.execute();
        }
    }

}

Command 抽象命令

/**
 * @author duanyimiao
 * @create 2018-11-08 6:38 AM
 * @description 命令抽象类,命令实现委托于烧烤师傅
 **/
public abstract class Command {
    protected Barbecuer barbecuer;

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

    public abstract void execute();
}

Barbecuer 命令接受者

/**
 * @author duanyimiao
 * @create 2018-11-08 6:40 AM
 * @description 烧烤师傅,命令接受者
 **/
public class Barbecuer {

    public void bakeMutton(){
        System.out.println("bake mutton");
    }

    public void bakeChickenWing(){
        System.out.println("bake chicken wing");
    }

    public void bakeBeef(){
        System.out.println("bake beef");
    }
}

BakeBeefCommand 烤牛肉命令

/**
 * @author duanyimiao
 * @create 2018-11-08 6:50 AM
 * @description 烤牛肉命令
 **/
public class BakeBeefCommand extends  Command{

    public BakeBeefCommand(Barbecuer barbecuer){
        super(barbecuer);
    }

    @Override
    public void execute() {
        //具体制作牛肉交给烧烤师傅进行处理
        barbecuer.bakeBeef();
    }
}

BakeChickenWindCommand 烤鸡翅命令

/**
 * @author duanyimiao
 * @create 2018-11-08 6:50 AM
 * @description
 **/
public class BakeChickenWindCommand extends Command {

    public BakeChickenWindCommand(Barbecuer barbecuer){
        super(barbecuer);
    }

    @Override
    public void execute() {
        //具体制作鸡翅交给烧烤师傅进行处理
        barbecuer.bakeChickenWing();
    }
}

BakeMuttonCommand 烤羊肉命令

/**
 * @author duanyimiao
 * @create 2018-11-08 6:50 AM
 * @description
 **/
public class BakeMuttonCommand extends Command{

    public BakeMuttonCommand(Barbecuer barbecuer){
        super(barbecuer);
    }

    @Override
    public void execute() {
        //具体制作羊肉交给烧烤师傅进行处理
        barbecuer.bakeMutton();
    }
}

Client:测试类

/**
 * @author duanyimiao
 * @create 2018-11-08 6:56 AM
 * @description
 **/
public class Client {

    public static void main(String[] args) {
        Barbecuer barbecuer = new Barbecuer();
        Command bakeBeefCommand1 = new BakeBeefCommand(barbecuer);
        Command bakeBeefCommand2 = new BakeBeefCommand(barbecuer);
        Command bakeChickenWindCommand = new BakeChickenWindCommand(barbecuer);
        Command bakeMuttonCommand1 = new BakeMuttonCommand(barbecuer);
        Command bakeMuttonCommand2 = new BakeMuttonCommand(barbecuer);
        Command bakeMuttonCommand3 = new BakeMuttonCommand(barbecuer);

        Waiter waiter = new Waiter();
        waiter.setOrder(bakeBeefCommand1);
        waiter.setOrder(bakeBeefCommand2);
        waiter.setOrder(bakeChickenWindCommand);
        waiter.setOrder(bakeMuttonCommand1);
        waiter.setOrder(bakeMuttonCommand2);
        waiter.setOrder(bakeMuttonCommand3);
        //撤销一个羊肉串
        waiter.cancelOrder(bakeMuttonCommand3);
        //重做羊肉串
        waiter.setOrder(bakeMuttonCommand3);
        waiter.notifyToMake();


    }
}

输出结果:

增加订单 com.dynamo.command.BakeBeefCommand@108c4c35 时间 Wed Nov 28 11:37:31 CST 2018
增加订单 com.dynamo.command.BakeBeefCommand@4629104a 时间 Wed Nov 28 11:37:31 CST 2018
sorry chicken wind was sold out
增加订单 com.dynamo.command.BakeMuttonCommand@27f8302d 时间 Wed Nov 28 11:37:31 CST 2018
增加订单 com.dynamo.command.BakeMuttonCommand@4d76f3f8 时间 Wed Nov 28 11:37:31 CST 2018
增加订单 com.dynamo.command.BakeMuttonCommand@2d8e6db6 时间 Wed Nov 28 11:37:31 CST 2018
取消订单 com.dynamo.command.BakeMuttonCommand@2d8e6db6 时间 Wed Nov 28 11:37:31 CST 2018
增加订单 com.dynamo.command.BakeMuttonCommand@2d8e6db6 时间 Wed Nov 28 11:37:31 CST 2018
bake beef
bake beef
bake mutton
bake mutton
bake mutton

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值