命令模式

来源:互联网 发布:数据通信与网络 编辑:程序博客网 时间:2024/05/01 23:19

  某天接到客户的需求,我们的项目需要增加新需求,项目经理找到需求组同事说我们需要增加一条需求,然后找到UI设计组同事说我们需要增加一条需求做好ui设计,然后跑到代码组同事说我们要增加一条需求赶紧准备撸代码,最后跑到测试组同事说我们要增加一条需求赶紧写好测试用例。我们现在来用代码实现这个过程。
抽象组:

public abstract class Group{    //找到改组的人    public abstract void  find();    //增加一条需求    public abstract void add();    //删除一条需求    public abstract void delete();}

需求组:

public class RequirementGroup extends Group{    @Override    public void find()    {        // TODO Auto-generated method stub        System.out.println("找到需求组");    }    @Override    public void add()    {        // TODO Auto-generated method stub        System.out.println("增加一条需求");    }    @Override    public void delete()    {        // TODO Auto-generated method stub        System.out.println("删除一条需求");    }

UI设计组:

public class UIDesignGroup extends Group{    @Override    public void find()    {        // TODO Auto-generated method stub        System.out.println("找到ui设计组");    }    @Override    public void add()    {        // TODO Auto-generated method stub        System.out.println("增加一条需求");    }    @Override    public void delete()    {        // TODO Auto-generated method stub        System.out.println("删除一条需求");    }}

代码组:

public class CodeGroup extends Group{    @Override    public void find()    {        // TODO Auto-generated method stub        System.out.println("找到代码组");    }    @Override    public void add()    {        // TODO Auto-generated method stub        System.out.println("增加一条需求");    }    @Override    public void delete()    {        // TODO Auto-generated method stub        System.out.println("删除一条需求");    }}

测试组:

public class TestGroup extends Group{    @Override    public void find()    {        // TODO Auto-generated method stub        System.out.println("找到测试组");    }    @Override    public void add()    {        // TODO Auto-generated method stub        System.out.println("增加一条需求");    }    @Override    public void delete()    {        // TODO Auto-generated method stub        System.out.println("删除一条需求");    }}

场景类:

public class Client{    public static void main(String[] args)    {        System.out.println("========找到需求组,增加需求=====");        RequirementGroup requirementGroup  = new RequirementGroup();        requirementGroup.find();        requirementGroup.add();        System.out.println("========找到UI设计组,增加需求=====");        UIDesignGroup uiDesignGroup = new UIDesignGroup();        uiDesignGroup.find();        uiDesignGroup.add();        System.out.println("========找到代码组,增加需求=====");        CodeGroup codeGroup = new CodeGroup();        codeGroup.find();        codeGroup.add();        System.out.println("========找到测试组,增加需求=====");        TestGroup testGroup = new TestGroup();        testGroup.find();        testGroup.add();        System.out.println("========终于增加需求成功=====");    }}

执行结果:

========找到需求组,增加需求=====找到需求组增加一条需求========找到UI设计组,增加需求=====找到ui设计组增加一条需求========找到代码组,增加需求=====找到代码组增加一条需求========找到测试组,增加需求=====找到测试组增加一条需求========终于增加需求成功=====

  代码写完了,会发现问题,假如这个项目经理叫你当,你会担任吗?肯定不会,当客户需求不断变化时项目经理都会累死,工作效率低下,各部门同事会嫌弃死你,肯定不会去背这锅。下面对我们的代码进行修改让你能胜任这个项目经理职位。
把增加/删除需求的操作封装成命令:
抽象命令:

public abstract class Command{    RequirementGroup requirementGroup = new RequirementGroup();    UIDesignGroup uiDesignGroup = new UIDesignGroup();    CodeGroup codeGroup = new CodeGroup();    TestGroup testGroup = new TestGroup();    public abstract void execute();}

增加需求命令:

public class AddRequirementCommand extends Command{    @Override    public void execute()    {        // TODO Auto-generated method stub        super.requirementGroup.find();        super.requirementGroup.add();        super.uiDesignGroup.find();        super.uiDesignGroup.add();        super.codeGroup.find();        super.codeGroup.add();        super.testGroup.find();        super.testGroup.add();    }}

删除需求命令:

public class DeleteRequirementCommand extends Command{    @Override    public void execute()    {        // TODO Auto-generated method stub        super.requirementGroup.find();        super.requirementGroup.delete();        super.uiDesignGroup.find();        super.uiDesignGroup.delete();        super.codeGroup.find();        super.codeGroup.delete();        super.testGroup.find();        super.testGroup.delete();    }}

项目经理:

public class Invoker{    private Command command;    public Command getCommand()    {        return command;    }    public void setCommand(Command command)    {        this.command = command;    }    public void action()    {        this.command.execute();    }}

各组(需求组,ui设计组,代码组,测试组)的代码不变,不在重写。

场景类:

public class Client1{        public static void main(String[] args)        {            Invoker invoker = new Invoker();            Command addCommand = new AddRequirementCommand();            Command deleteCommand  = new DeleteRequirementCommand();            invoker.setCommand(addCommand);            invoker.action();            invoker.setCommand(deleteCommand);            invoker.action();        }}

执行结果:

找到需求组增加一条需求找到ui设计组增加一条需求找到代码组增加一条需求找到测试组增加一条需求找到需求组删除一条需求找到ui设计组删除一条需求找到代码组删除一条需求找到测试组删除一条需求

  改装后的代码可以发现项目经理只需要接收客户发送命令(增加/删除需求),然后执行自己的action()方法就可以完成需求的增加和删除,实现的过程不需要项目经理去参与,这样的项目经理相信你能胜任。这就是命令模式。
  
命令模式定义
  命令模式:Encapsulate a request as an object,thereby letting you parameterize clients with different requests,queue or log requests,and support undoable operations.(将一个请求对象封装成一个对象,从而让你使用不同的请求把客户端参数化,把请求排队或者记录请求日志,可以提供命令的撤销和 恢复功能。)
  
命令模式角色
  Receive接受者角色:具体的干活角色,命令传送到这里就要执行,对应上述例子的各个group,可以把receive抽象化,然后接受不同的命令。
  Command命令角色:需要执行的所有命令都在这里执行。
  Invoke调用者角色:接收到命令,执行命令。比如例子中的项目经理。

命令模式的优点
  类间解耦:调用者角色与接收者角色直接没有任何依赖关系。
  可扩展性:Command的子类可以很容易的扩展。
  命令模式结合其他模式会更优秀:结合模板方法模式可以减少Command子类的膨胀问题。
命令模式的缺点
  Command子类不断膨胀。

0 0
原创粉丝点击