androidJAVA设计模式互联网科技

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

2018-04-18  本文已影响51人  zhang_pan

前言

命令模式是一个高内聚的模式,其定义为: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

上一篇 下一篇

猜你喜欢

热点阅读