设计模式之命令模式-命令之下出效率(Command)

问题

我的电脑城的有多个销售经理,有一个配件管理员。之前的模式是销售经理接待客户,客户提出需求,销售经理告诉配件管理员,例如三星1t固态硬盘一个,罗技键盘一个等等。配件管理员记录之后,从仓库拿出配件,再交付给对应客户。这样就出了个问题,在忙的时候,一个管理员需要对多个销售经理,然后需求不同,记录并取货,还有的时候,客户定下来之后又后悔了,不要了或者想换个别的,管理员就被销售经理给折腾疯了,根本不知道哪些是需要的,哪些是不需要的,还经常拿错了配件给到客户。这样下去可不行啊,乱糟糟的流程导致员工们经常出错。这就需要我们今天的主题——命令模式了。

简介

命令模式如何解决这个问题呢?首先销售经理不能一个配件一个配件的告知管理员,而是根据客户需要把需要的配件列成清单,管理员只接收清单的任务,根据清单拿对应的配件。顾客取消清单,则有销售经理告知xx清单取消即可。就非常简洁得解决了这个问题。其核心思想就是将客户需求转为一条包含所有需求的命令,可以对这个命令延迟执行,撤销,恢复等操作。这个其实也可以类比于饭店厨师做菜,开始生意少的时候,顾客点菜后,服务端都是高喊一声鱼香肉丝一份,宫保鸡丁一份等等,厨师听到后开始做菜,后来生意好了之后,厨师忙不过来,根本听不到服务员喊的菜名。这时候,服务员就会记录下顾客的做菜需求,然后将清单给到厨房,厨房拿到做菜清单之后,将其放在菜单队列,依序取出菜单进行做菜。我们来看看如何实现吧。

实现

Command抽象类

public abstract class Command {

    /**
     * 模拟顾客的需求
     */
    protected String info;

    abstract void execute();
}

具体的命令类

public class CacheCommand extends Command {

    public CacheCommand(String info) {
        this.info = info;
    }

    @Override
    void execute() {
        System.out.println("buy cache: " + info);
    }
}

public class DiskCommand extends Command{

    public DiskCommand(String info) {
        this.info = info;
    }

    @Override
    void execute() {
        System.out.println("buy disk: " + info);
    }
}

public class KeyboardCommand extends Command{

    public KeyboardCommand(String info) {
        this.info = info;
    }

    @Override
    void execute() {
        System.out.println("buy keyboard: " + info);
    }
}

销售经理

public class Salesman {

    public Salesman(Keeper keeper) {
        this.keeper = keeper;
        commandList = new LinkedList<>();
    }

    private Keeper keeper;

    private Queue<Command> commandList;


    public void addCommand(Command command) {
        commandList.add(command);
    }

    public void cancelCommand(Command command) {
        System.out.println("顾客取消: " + command.info);
        commandList.remove(command);
    }

    public void execute() {
        System.out.println("顾客下单,通知管理员取配件");
        for (Command command : commandList) {
            keeper.execute(command);
        }
    }

}

管理员

public class Keeper {

    public void execute(Command command) {
        command.execute();
    }

}

执行

    public static void main(String[] args) {
        CacheCommand cacheCommand = new CacheCommand("8G");
        DiskCommand diskCommand = new DiskCommand("1T SSD");
        KeyboardCommand keyboardCommand = new KeyboardCommand("luoji");

        Keeper keeper = new Keeper();
        Salesman salesman = new Salesman(keeper);
        salesman.addCommand(cacheCommand);
        salesman.addCommand(diskCommand);
        salesman.addCommand(keyboardCommand);
        salesman.execute();

        salesman.cancelCommand(diskCommand);
        salesman.execute();
    }

执行结果

顾客下单,通知管理员取配件
buy cache: 8G
buy disk: 1T SSD
buy keyboard: luoji
顾客取消: 1T SSD
顾客下单,通知管理员取配件
buy cache: 8G
buy keyboard: luoji

总结

总结上面的代码,顾客有三个需求,分别是8G的内存,1T的SSD和罗技的键盘,销售经理将其封装成三个命令,列在清单上,当顾客确定下单后,销售经理就通知管理员根据清单上的内容拿对应的配件即可。当然在下单之前,顾客取消了硬盘的需求,那么就从订单清单中移出。

命令模式的作用是将请求方和执行方进行解耦:例如顾客和配件管理员之间增加销售经理,顾客和厨师之间增加服务员。将请求转成独立对象:顾客需要某某品牌的机械键盘,颜色要求,轴距要求等等信息可以封装成独立对象,给到执行方,更加清晰明了。支持撤销操作

优点:开闭原则:轻松增加新的命令;单一职责:每个命令只完成自己的职责;可实现撤销和恢复操作;解耦

缺点:解耦产生的缺点也就是增加了系统的复杂性,命令过多的话,会添加较多的实现类。

命令模式从理解上来说相对晦涩一些。首先命令模式解放了执行者,执行者只专注于执行,接受到命令,执行即可。其他操作由中间者完成(很多设计模式均有类似思想)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值