美文网首页
设计模式-命令模式(十五)

设计模式-命令模式(十五)

作者: 巨子联盟 | 来源:发表于2018-05-26 16:22 被阅读0次

命令模式又称:行动模式 或 交易模式
使用了命令模式,客户端就不在直接与Receiver打交道,而把执行的细节交于Invoker处理,ConcreteCommand封装了具体的细节.

实现命令模式的轻重之分:
轻就是它只提供一个和接收之间的耦合而已
重就是应当实现所有细节,这时就不再需要接收者了.
我们也可以用一个具体命令者ConcreteCommand动态的调用其Receiver处理某一个事项.

上类图:


命令模式.png

实例:Java JWT的事件处理,录音机的功能

  • 示例代码:
  1. 创建命令的抽象接口
package com.byedbl.command.method2;

/**
 * 命令角色,声明了一个所有的命令类需要实现的接口
 */
public interface Command {

    void execute();
}

  1. 实现一个具体 的命令
package com.byedbl.command.method2;

/**
 * 具体命令角色,实现了声明的命令接口
 */
public class ConcreteCommand implements Command {
    private Receiver receiver;

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

    public void execute() {
        receiver.action();
    }
}

  1. 创建一个命令接收者
package com.byedbl.command.method2;

/**
 * 负责具体实施和 执行一个请求
 */
public class Receiver {

    /**
     * 行动方法
     */
    public void action() {
        System.out.println("receive a command");
    }
}

  1. 负责调用命令的对象Invoker
package com.byedbl.command.method2;

/**
 *负责调用命令对象执行请求
 */
public class Invoker {
    private Command command;

    public Invoker(Command command) {
        this.command = command;
    }

    /**
     * 这个叫行动方法
     */
    public void action() {
        command.execute();
    }
}

  1. 客户端调用
package com.byedbl.command.method2;

import static org.junit.Assert.*;

/**
 * <pre>
 * 客户角色,创建一个具体命令,并确定其 接收者
 *
 * 为什么不直接将Receiver注册到Invoker里面?而要先注册到Command里面?
 * 假设我们现在直接将Receiver注册到Invoker里面,那么Invoker的 action方法怎么调Receiver的方法呢?要知道Invoker是可以没有一个通用的接口的.
 * 我们发现只能重写一个Invoker了.
 * 那我们抽象一个接口,比如现在的Command,command的里面有一个给Invoker调用的方法execute,
 * 这时我们Invoker就能得到很好的重用,也符合开闭原则,
 * 当我们要调用一个其他的动作时,我们只要实现一个Command 的接口即可,实现的Command可以简单的委托给Receiver处理,
 * 极端情况也可以不要Receiver,具体的Command就处理了全部的逻辑.这时模式就变成了一堆不同命令的策略模式+一个Invoker
 *
 * 那为什么不 直接用策略模式呢?
 * 关键是多了个Invoker类,这个调用各种策略的通用类,可以说是在策略模式上更进了一步,
 * 告诉了我们怎么通用调用策略的方法(不仅仅是可以用反射)
 *
 * 用途场景:undo 功能
 */
public class CommandTest {

    @org.junit.Test
    public void execute() {
        Receiver receiver = new Receiver();
        Command command = new ConcreteCommand(receiver);
        Invoker invoker = new Invoker(command);
        invoker.action();

    }
}
  • 优点

  1. 把请求一个操作对象Invoker与知道怎么执行一个操作的对象Receiver分隔开

相关文章

网友评论

      本文标题:设计模式-命令模式(十五)

      本文链接:https://www.haomeiwen.com/subject/wqiujftx.html