设计模式之命令模式(十二)

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

  已经参加工作的小伙伴是不是常常遇到这种事情,项目经理加需求,需求变动,项目工期。程序员除了每天敲代码还要和项目经理的沟通。项目经理和程序员的关系可以看成是命令模式。

什么是命令模式?

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

命令模式有哪几种角色?

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 orders = new LinkedList();


// 新增需求
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
新增一个需求
新增一个需求

命令模式的适用场景

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

小结

  通过例子看出项目经理发布命令,程序员执行命令,项目经理和程序员是相辅相成,缺一不可,都很重要。看来设计模式无处不在呀。


版权声明:
作者:玉兰
链接:https://www.techfm.club/p/45202.html
来源:TechFM
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>