命令模式

  某天接到客户的需求,我们的项目需要增加新需求,项目经理找到需求组同事说我们需要增加一条需求,然后找到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子类不断膨胀。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值