设计模式之命令模式

来源:互联网 发布:模拟投资基金软件 编辑:程序博客网 时间:2024/06/05 09:37

1. 命令模式的引入

1.1 有三个组分别为需求组、美工组、代码组,客户对开发的产品有些地方需要修改,修改对应的功能就要找到对应的组别。如下UML:

这里写图片描述

具体代码实现:

abstract class Group{    //甲乙双方式分开办公,所以甲方需要通过find方法来找到对应的组    public abstract void find();    //增加一个功能    public abstract void add();    public abstract void delete();}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("客户要求删除一项需求。。。");    }}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("客户要求删除一项功能。。。");    }}class PageGroup extends Group{    public void find() {        System.out.println("客户找到美工组...");    }    public void add() {        System.out.println("客户要求新增一个页面...");    }    public void delete() {        System.out.println("客户要求删除一个页面...");    }}public class Client {    public static void main(String[] args) {        Group group = new RequirementGroup();        group.find();        group.add();        group = new PageGroup();        group.find();        group.add();        group = new CodeGroup();        group.find();        group.add();    }}

这样问题出现了,客户需要了解每个组的职能,然后根据自己需求找到具体的组别,而不是关注自己的命令是否被执行了。

1.2 我们对上述实现方式进行优化,增加一个Invoker 来屏蔽客户对组别的依赖。

UML

具体代码实现:

abstract class Group{    //甲乙双方式分开办公,所以甲方需要通过find方法来找到对应的组    public abstract void find();    //增加一个功能    public abstract void add();    public abstract void delete();}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("客户要求删除一项需求。。。");    }}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("客户要求删除一项功能。。。");    }}class PageGroup extends Group{    public void find() {        System.out.println("客户找到美工组...");    }    public void add() {        System.out.println("客户要求新增一个页面...");    }    public void delete() {        System.out.println("客户要求删除一个页面...");    }}class Invoker{    private String command;    public Invoker(String command) {        super();        this.command = command;    }    public void execute(){        if("addRequirement".equals(command)){            Group group = new RequirementGroup();            group.find();            group.add();        }else if("addPage".equals(command)){            Group group = new PageGroup();            group.find();            group.add();        }    }}public class Client {    public static void main(String[] args) {        Invoker invoker = new Invoker("addRequirement");        invoker.execute();    }}

这样优化后还是存在问题,一是字符串是没有约束力的,二是对于扩展不方便。为了把命令的接受者(Group)和命令发起者分离。使命令的发起者和命令(Command)关联,这样命令发起者只需要知道有什么命令就可以了。

这样我们就引入了命令模式

2. 命令模式

命令模式UML

  • 组别GroupCommand 抽象类中创建,初始化Invoker 时需要传入Command
  • 具体代码实现:
abstract class Group{    //甲乙双方式分开办公,所以甲方需要通过find方法来找到对应的组    public abstract void find();    //增加一个功能    public abstract void add();    public abstract void delete();}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("客户要求删除一项需求。。。");    }}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("客户要求删除一项功能。。。");    }}class PageGroup extends Group{    public void find() {        System.out.println("客户找到美工组...");    }    public void add() {        System.out.println("客户要求新增一个页面...");    }    public void delete() {        System.out.println("客户要求删除一个页面...");    }}abstract class Command{    protected Group codeGroup = new CodeGroup();    protected Group pageGroup = new PageGroup();    protected Group requirementGroup = new RequirementGroup();    public abstract void execute();}class AddFunctionCommand extends Command{    @Override    public void execute() {        super.codeGroup.find();        super.codeGroup.add();    }}class AddPageCommand extends Command{    @Override    public void execute() {        super.pageGroup.find();        super.pageGroup.add();    }}class AddRequirementCommand extends Command{    @Override    public void execute() {        super.requirementGroup.find();        super.requirementGroup.add();    }}class Invoker{    private Command command;    public Invoker(Command command) {        super();        this.command = command;    }    public void execute(){        command.execute();    }}public class Client {    public static void main(String[] args) {        Invoker invoker = new Invoker(new AddRequirementCommand());        invoker.execute();        invoker = new Invoker(new AddPageCommand());        invoker.execute();        invoker = new Invoker(new AddFunctionCommand());        invoker.execute();    }}

运行结果:

找到需求组。。。
客户要求增加一项需求。。。
客户找到美工组…
客户要求新增一个页面…
客户找到代码组。。。
客户要求增加一项功能。。。

小结

命令模式的优点:

  1. 实现类之间的解耦(之前客户直接与各组相关联,优化后客户只与命令相关联)
  2. 具有可扩展型,扩展一个命令特别简单

缺点:

  1. 命令泛滥,N种组合命令
0 0