设计模式(命令模式)

本文详细探讨了命令模式在软件设计中的应用,强调其优点如类间解耦和可扩展性,同时也指出随着命令数量增加可能导致的类膨胀问题。通过实例展示了如何使用命令模式结合其他模式优化代码结构。
摘要由CSDN通过智能技术生成

将命令封装成一个对象, 由调用者执行

优点

  • 类间解耦:
    调用者角色与接收者角色之间没有任何依赖关系,
    调用者实现功能时只需调用Command 抽象类的execute方法就可以,
    不需要了解到底是哪个接收者执行。
  • 可扩展性:
    Command的子类可以非常容易地扩展,
    而调用者Invoker和高层次的模块Client不产生严 重的代码耦合。
  • 命令模式结合其他模式会更优秀:
    命令模式可以结合责任链模式,实现命令族解析任务;
    结合模板方法模式,则可以减少 Command子类的膨胀问题。

缺点

  • 如果有N个命令,问题就出来 了,
    Command的子类就可不是几个,而是N个,
    这个类膨胀得非常大。
    /**
     * 订单信息, 可以添加多个
     */
    class Order {
        // 订单编号,模拟单号递增
        int orderNum;
        // 订单容器, 存放订单名称和数量
        Map<String, Integer> orders = new HashMap<>();
        public void setFood(String foodName, int count) {
            orderNum++;
            orders.put(foodName, count);
        }
    }

Receiver类,知道如何实施与执行一个与请求相关的操作,任何类都可能作为一个接受者

    /**
     * 厨师信息, 提供出餐方法
     */
    class Chef {
        void makeFood(String orderName, int number) {
            System.out.printf("厨师制作 %d份 %s %n", number, orderName);
        }
    }

Command类,用来声明执行操作的接口

     /**
     * 命令接口
     */
	 interface Command {
	        void execute();
	 }
     /**
     * 核心类, 聚合厨师和订单信息
     */
    class CommandImpl implements Command {

        Chef chef;
        Order order;

        public CommandImpl(Chef chef, Order order) {
            this.chef = chef;
            this.order = order;
        }

        @Override
        public void execute() {
            System.out.println("CommandImpl before current 共" + order.orderNum + "单");
            Map<String, Integer> orders = order.orders;
            Set<String> keySet = orders.keySet();
            for (String food : keySet) {
                chef.makeFood(food, orders.get(food));
            }
            System.out.println("CommandImpl after");
        }
    }

Execute

    /**
     * 服务员, 专注于执行命令
     */
    class Waiter {
        List<Command> commands = new ArrayList<>();

        public void setCommands(Command command) {
            this.commands.add(command);
        }

        public void sendCommand() {
            for (Command command : commands) {
                if (command != null) {
                    command.execute();
                }
            }
        }
    }

Run

    @Test
    public void client() {
        // 创建订单
        Order order = new Order();
        order.setFood("炒拉条", 2);
        order.setFood("果汁", 1);
        order.setFood("可乐", 1);

        // 创建厨师
        Chef john = new Chef();

        // 通过订单和厨师信息构建出命令对象
        Command command = (Command) new CommandImpl(john, order);

        // 执行命令
        Waiter amy = new Waiter();
        amy.setCommands(command);
        amy.sendCommand();
    }

CommandImpl before current 共3单
厨师制作 2份 炒拉条
厨师制作 1份 果汁
厨师制作 1份 可乐

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值