美文网首页androidJAVA设计模式互联网科技
Android 架构师5 设计模式之命令模式

Android 架构师5 设计模式之命令模式

作者: zhang_pan | 来源:发表于2018-04-18 10:23 被阅读51次

    前言

    命令模式是一个高内聚的模式,其定义为:Encapsulate a request as an object,there by letting you parameterize clients with different requests,queue or log requests,and support undoable operations.(将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请 求排队或者记录请求日志,可以提供命令的撤销和恢复功能。

    需求

    一个项目中有需求组、美工组、代码组,刚开始的时候客户还是很乐意和我们每个组探讨,比如和需求组讨论需求,和美工讨论页面,和代码组讨论实现,告诉他们修改这里,删除这里,增加这些等等。

    命令模式.png

    基本实现与问题

    组的抽象类Group,毕竟面向接口编程嘛:

    public abstract class Group {
        //首先找到对应的组
        public abstract void find();
        //被要求添加一个功能
        public abstract void add();
        //被要求删除一个功能
        public abstract void delete();
        //被要求改变一个功能
        public abstract void change();
        //被要求给出所有的变更计划
        public abstract void plan();
    }
    

    需求组RequirementGroup:

    public class RequirementGroup extends Group {
        @Override
        public void find() {
            System.out.println("找到需求组...");
        }
    
        @Override
        public void add() {
            System.out.println("客户要求增加一个需求...");
        }
    
        @Override
        public void delete() {
            System.out.println("客户要求删除一个需求...");
        }
    
        @Override
        public void change() {
            System.out.println("客户要求改变一个需求...");
        }
    
        @Override
        public void plan() {
            System.out.println("客户要求需求变更计划...");
        }
    }
    

    美工组PageGroup:

    public class PageGroup extends Group {
        @Override
        public void find() {
            System.out.println("找到美工组...");
        }
    
        @Override
        public void add() {
            System.out.println("客户要求增加一个页面...");
        }
    
        @Override
        public void delete() {
            System.out.println("客户要求删除一个页面...");
        }
    
        @Override
        public void change() {
            System.out.println("客户要求改变一个页面...");
        }
    
        @Override
        public void plan() {
            System.out.println("客户要求界面修改计划...");
        }
    }
    

    代码组CodeGroup:

    public class CodeGroup extends Group {
        @Override
        public void find() {
            System.out.println("找到代码组...");
        }
    
        @Override
        public void add() {
            System.out.println("客户要求增加一个功能...");
        }
    
        @Override
        public void delete() {
            System.out.println("客户要求删除一个功能...");
        }
    
        @Override
        public void change() {
            System.out.println("客户要求改变一个功能...");
        }
    
        @Override
        public void plan() {
            System.out.println("客户要求修改功能计划...");
        }
    }
    

    整个项目的三个支柱已经产生了,接下来就要看看客户Client端怎么跟我们沟通了:

    public class Client {
        public static void main(String[] args) {
            Group group = new RequirementGroup();
            group.find();
            group.add();
            group.plan();
        }
    }
    

    这是客户增加一个需求,由需求组去处理,代码输出结果为:

    找到需求组...
    客户要求增加一个需求...
    客户要求需求变更计划...
    

    这时候,客户需要美工组增加一个页面,代码实现是这样的:

    public class Client {
        public static void main(String[] args) {
            Group group = new PageGroup();
            group.find();
            group.add();
            group.plan();
        }
    }
    

    显然对于这样的修改是可以接受的,但是如果现实生活中,每有一个需求都需要客户单独找需求组或者美工组或者代码组去,恐怕客户和每个组都是不乐意这么去做的吧!这时候客户就跟产品经理说,你们别这样麻烦了,给我一个接头人,我发出需求的命令给你这个接头人,然后你们内部怎么处理,就由这个接头人去安排吧!接下来我们看命令模式是怎么实现的。

    命令模式

    提供一个命令的抽象类Command:

    public abstract class Command {
        protected RequirementGroup rg = new RequirementGroup();
        protected PageGroup pg = new PageGroup();
        protected CodeGroup cg = new CodeGroup();
        //执行事情的方法
        public abstract void execute();
    }
    

    增加一个需求的命令类AddRequirementCommand:

    public class AddRequirementCommand extends Command {
        @Override
        public void execute() {
            rg.find();
            rg.add();
            rg.plan();
        }
    }
    

    删除一个页面的命令类DeletePageCommand:

    public class DeletePageCommand extends Command {
        @Override
        public void execute() {
            pg.find();
            pg.delete();
            pg.plan();
        }
    }
    

    接头人Invoker:

    public class Invoker {
        private Command command;
    
        public void setCommand(Command command) {
            this.command = command;
        }
    
        public void execute() {
            if (command != null) {
                command.execute();
            }
        }
    }
    

    这时候客户端的请求是这样的:

    public class Client {
        public static void main(String[] args) {
            Invoker invoker = new Invoker();
            AddRequirementCommand command = new AddRequirementCommand();
            invoker.setCommand(command);
            invoker.execute();
        }
    }
    

    运行结果为:

    找到需求组...
    客户要求增加一个需求...
    客户要求需求变更计划...
    

    如果是删除一个页面的命令,我们只需要new DeletePageCommand()即可,是不是很简单呢?而且满足对修改关闭,对扩展开放的设计原则。更令人满意的是,如果有一个需求,需要三个小组配合完成,也是非常简单的,只需要重新设计一个Command的实现类即可。

    总结

    命令模式比较简单,但是在项目中使用是非常频繁的,封装性比较好,将请求者和执行者分开了,扩展性也有很好的保障;但是由于需求不断地增加,可能会导致Command的实现类过多。

    喜欢本篇博客的简友们,就请来一波点赞,您的每一次关注,将成为我前进的动力,谢谢!作者:zhang_pan

    相关文章

      网友评论

      • IT人故事会:太感谢了,学了好多东西!
        zhang_pan:@IT人故事会 嘿嘿,感兴趣的话,可以点一波关注

      本文标题:Android 架构师5 设计模式之命令模式

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