设计模式(十五)命令模式

作者: 我犟不过你 | 来源:发表于2021-01-12 16:51 被阅读0次

    1、概述

    命令模式是一种行为设计模式, 它可将请求转换为一个包含与请求相关的所有信息的独立对象。 该转换让你能根据不同的请求将方法参数化、 延迟请求执行或将其放入队列中, 且能实现可撤销操作。

    在java中本质可以理解为是以接口作为参数传递。

    2、适用场景

    1)如果你需要通过操作来参数化对象, 可使用命令模式。
    2)如果你想要将操作放入队列中、 操作的执行或者远程执行操作, 可使用命令模式。
    3)如果你想要实现操作回滚功能, 可使用命令模式。

    3、实例

    有以下场景:

    有一个饭店,饭店内有东北菜师傅和川菜师傅,还有一个店小二。
    初始负责做菜,小二负责给客户点菜和通知厨师做菜。
    

    厨师接口:

    /**
     * 厨师接口
     * @date: 2021/1/12
     * @author weirx
     * @version 3.0
     */
    public interface ICooker {
    
        /**
         * 烹饪
         */
        void doCooking();
    
        /**
         * 停止烹饪
         */
        void stopCooking();
    }
    

    菜品接口:

    /**
     * 菜品接口
     * @date: 2021/1/12
     * @author weirx
     * @version 3.0
     */
    public interface IDishes {
    
        /**
         * 下单
         */
        void order();
    
        /**
         * 退单
         */
        void back();
    }
    

    川菜厨师:

    /**
     * 四川厨师
     * @date: 2021/1/12
     * @author weirx
     * @version 3.0
     */
    public class SichuanCooker implements ICooker{
        @Override
        public void doCooking() {
            System.out.println("四川厨师正在烹饪");
        }
    
        @Override
        public void stopCooking() {
            System.out.println("四川厨师停止烹饪了");
        }
    }
    

    东北菜厨师:

    /**
     * 东北厨师
     * @date: 2021/1/12
     * @author weirx
     * @version 3.0
     */
    public class NortheastCooker implements ICooker{
        @Override
        public void doCooking() {
            System.out.println("东北厨师正在烹饪");
        }
    
        @Override
        public void stopCooking() {
            System.out.println("东北厨师停止烹饪了");
        }
    }
    

    川菜:

    /**
     * 四川菜
     * @date: 2021/1/12
     * @author weirx
     * @version 3.0
     */
    public class SichuanDishes implements IDishes{
        private ICooker cooker;
    
        public SichuanDishes(ICooker cooker) {
            this.cooker = cooker;
        }
        @Override
        public void order() {
            System.out.println("顾客下单四川菜");
            cooker.doCooking();
        }
    
        @Override
        public void back() {
            System.out.println("顾客取消四川菜订单了");
            cooker.stopCooking();
        }
    }
    

    东北菜:

    /**
     * 东北菜
     * @date: 2021/1/12
     * @author weirx
     * @version 3.0
     */
    public class NortheastDishes implements IDishes {
        private ICooker cooker;
    
        public NortheastDishes(ICooker cooker) {
            this.cooker = cooker;
        }
    
        @Override
        public void order() {
            System.out.println("顾客下单东北菜");
            cooker.doCooking();
        }
    
        @Override
        public void back() {
            System.out.println("顾客取消东北菜订单了");
            cooker.stopCooking();
        }
    }
    

    小二:

    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 服务员
     * @date: 2021/1/12
     * @author weirx
     * @version 3.0
     */
    public class Waiter {
    
        /**
         * 菜单
         */
        private List<IDishes> list = new ArrayList<>();
    
        /**
         * 顾客下单
         * @param dishes
         */
        public void order(IDishes dishes) {
            list.add(dishes);
        }
    
        /**
         * 顾客退单
         * @param dishes
         */
        public void back(IDishes dishes) {
            for (IDishes d : list) {
                if (d.getClass().getName().equals(d.getClass().getName())) {
                    list.remove(dishes);
                }
            }
        }
    
        /**
         * 通知厨师下单
         */
        public void doCooking() {
            for (IDishes d : list) {
                d.order();
            }
        }
    
        /**
         * 通知厨师退单
         * @param dishes
         */
        public void stopCooking(IDishes dishes) {
            dishes.back();
        }
    
        /**
         * 查看菜单
         */
        public void searchDishesList(){
            System.out.println("当前菜单:");
            for (IDishes d : list) {
                System.out.println(d.getClass().getName());
            }
        }
    }
    

    测试类:

    /**
     * 测试类
     * @date: 2021/1/12
     * @author weirx
     * @version 3.0
     */
    public class TestDemo {
    
        public static void main(String[] args) {
            Waiter waiter = new Waiter();
            SichuanDishes sichuanDishes = new SichuanDishes(new SichuanCooker());
            NortheastDishes northeastDishes = new NortheastDishes(new NortheastCooker());
            System.out.println("--------------顾客点单----------------");
            //顾客点单
            waiter.order(sichuanDishes);
            waiter.order(northeastDishes);
            waiter.searchDishesList();
            System.out.println("---------------小二下单---------------");
            //小二下单
            waiter.doCooking();
            System.out.println("---------------顾客退单四川菜---------------");
            //顾客退单四川菜
            waiter.back(sichuanDishes);
            waiter.stopCooking(sichuanDishes);
            waiter.searchDishesList();
            System.out.println("------------------------------");
        }
    }
    

    4、分析

    厨师 菜品 小二

    如上所示,在创建菜品时,需要指定厨师接口ICooker作为构造参数。而小二下单和通知厨师时,都是传递的菜品接口IDishes作为参数,符合命令模式。

    5、总结

    优点:
    1)单一职责原则。
    2)开闭原则。
    3)你可以实现撤销和恢复功能。
    4)你可以实现操作的延迟执行。
    5)你可以将一组简单命令组合成一个复杂命令。
    缺点:
    1)代码变得复杂

    相关文章

      网友评论

        本文标题:设计模式(十五)命令模式

        本文链接:https://www.haomeiwen.com/subject/figloktx.html