设计模式之命令模式

命令模式从名字上来理解就是老大发命令,小兵执行就是了,确实是这个意思。

                                                       

已经参加工作的小伙伴是不是常常遇到这种事情,项目经理加需求,需求变动,项目工期。如果没有参加工作的同学,程序员每天处理敲代码还有和项目经理的沟通。

 什么是命令模式?

将一个请求封装为一个对象,从而使你可用不同的请求客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。

 命令模式有哪几种角色?

Command:定义命令统一接口(项目经理法宝一、功能流程图)

ConcreteCommand:接口实现者,用来执行具体的命令。(项目经理法宝二、具体需求文档)

Receiver:命令的实际执行者(程序员)

Invoker:命令的请求者,是命令模式中最重要的角色,这个角色用对各个命令进行控制(项目经理)

 

命令模式类图 

 

经典代码

Command 声明执行操作的接口


public abstract class Command {
	// 具体执行者
    protected  Receiver receiver;

    public Command(Receiver receiver) {
        this.receiver = receiver;
    }

    public abstract void execute();
}

将一个接收者对象绑定一个动作,调用接收者相应操作实现execute方法


public class ConcreteCommand extends Command {

    public ConcreteCommand(Receiver receiver) {
        super(receiver);
    }

    @Override
    public void execute() {
 		// 调用具体执行
        receiver.action();
    }
}

Receiver类,知道如何实施与执行请求相关操作,任何类都可能作为一个接收者。 

public class Receiver {

    public void action () {
        System.out.println("执行请求!");
    }
}

Invoker类要求该命令执行这个请求

public class Invoker {

     private Command command;

     public void setCommand(Command command) {
         this.command = command;
     }

     public void executeCommand() {
         command.execute();
     }
}

测试方法

public static void main(String[] args) {
        Receiver receiver = new Receiver();

        Command command = new ConcreteCommand(receiver);
        Invoker invoker = new Invoker();

        invoker.setCommand(command);
        invoker.executeCommand();
 }

 

命令模式的优缺点

优点:

         它能较容易地设计一个命令队列。
         在需要的情况下,可以较容易地将命令记入日志。
         允许接收请求去的一方决定是否要否决请求。
         可以容易地实现对请求的撤销和重做
         由于加进新的具体命令类不影响其他的类,因此增加新的具体类命令类很容易。

缺点:

          类数量随命令数量增长而增长。可能造成类数量过多。     
          如果命令非常简单,实现起来就几行代码的事,而使用命令模式的话,不管命令多简单,都需要写一个命令类来封装。

 

有趣的代码

  声明执行操作的接口

public abstract class Command {

    protected Demand demand;

    public Command(Demand demand) {
        this.demand = demand;
    }

    public abstract void excuteCommand();
}

Java 程序员

public class JavaCommand extends Command {

    public JavaCommand(Demand barbecuer) {
        super(barbecuer);
    }

    @Override
    public void excuteCommand() {
        demand.addDemand();
    }
}

 Android程序员

public class AndroidCommand extends Command {

    public AndroidCommand(Demand barbecuer) {
        super(barbecuer);
    }

    @Override
    public void excuteCommand() {
        demand.addDemand();
    }
}

具体执行动作

public class Demand {

    public void addDemand() {
        System.out.println("新增一个需求");
    }

    public void modifyDemand () {
        System.out.println("修改一个需求");
    }
}

发布命令的项目经理

public class Manager {


    private List<Command> orders = new LinkedList<Command>();


    // 新增需求
    public void setOrder(Command command) {
        if (command.toString() .equals("com.company.JavaCommand@6d6f6e28") ) {
            System.out.println("这个需求不予更改,哈哈哈");
            System.out.println("拒绝需求"+command.toString()+"时间:"+new Date());
        } else {
            orders.add(command);
            System.out.println("新增需求"+command.toString()+"时间:"+new Date());
        }
    }
    // 取消需求
    public void cancelOrder(Command command) {
        orders.remove(command);
        System.out.println("取消需求"+command.toString()+"时间:"+new Date());
    }


    // 通知全部执行
    public void Notify() {

        for (Command command  :  orders) {
            command.excuteCommand();

        }
    }
}

测试方法

public static void main(String[] args) {
        Demand boy = new Demand();
        // 程序员
        Command bake1 = new AndroidCommand(boy);
        Command bake2 = new AndroidCommand(boy);
        Command bake3 = new JavaCommand(boy);

        // 项目经理
        Manager girl = new Manager();

        girl.setOrder(bake1);
        girl.setOrder(bake2);
        girl.setOrder(bake3);

        girl.Notify();

    }
}

执行结果

执行结果:
新增需求com.company.AndroidCommand@4554617c时间:Sun Mar 17 15:54:57 CST 2019
新增需求com.company.AndroidCommand@7f31245a时间:Sun Mar 17 15:54:57 CST 2019
这个需求不予更改,哈哈哈
拒绝需求com.company.JavaCommand@6d6f6e28时间:Sun Mar 17 15:54:57 CST 2019
新增一个需求
新增一个需求

命令模式的适用场景

对于大多数请求-响应模式的功能,比较适合使用命令模式,正如命令模式定义说的那样,命令模式对实现记录日志、撤销操作等功能比较方便。

小结

通过例子可以看出,项目经理类似于发布命令,程序员执行命令,项目经理和程序员是相辅相成,缺一不可,都很重要。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值