晋城婚介:设计模式 - 下令模式详解及其在JdbcTemplate中的应用

admin 6个月前 (04-26) 科技 56 0

基本先容

在软件设计中,我们经常需要向某些工具发送一些请求,然则并不知道请求的吸收者是谁,也不知道被请求的操作是哪个,我们只需要在程序运行时指定详细的请求吸收者即可,此时,可以使用下令模式来设计,使得请求发送者与请求吸收者消除彼此之间的耦合,让工具之间的挪用关系加倍天真。

下令模式(Command Pattern)可以对发送者和吸收者完全解耦,发送者与吸收者之间没有直接引用关系,发送请求的工具只需要知道若何发送请求,而不必知道若何完成请求。

下令模式将一个请求封装为一个工具,从而使我们可用差别的请求对客户举行参数化;对请求排队或者纪录请求日志,以及支持可打消的操作。

模式结构

  • Invoker:挪用者,发送下令

  • Receiver:吸收者,吸收下令

  • Command:抽象下令类,界说了所有的下令

  • ConcreteCommand:详细下令类,挪用吸收者的操作

举例说明

现有许多家电(电灯、电视机、空调....),每个家电都有自己的控制装置,若是需要控制它们,需要逐个开启、逐个关闭,这时候,若是有一个万能遥控器(如下如所示),操作差别的家电只需要按对应的按钮即可,若何使用下令模式实现?

1、建立电灯的下令吸收者

public class LightReceiver {
    public void on() {
        System.out.println("电灯打开了");
    }

    public void off() {
        System.out.println("电灯关闭了");
    }
}

2、建立抽象的下令接口

public interface Command {
    /**
     * 执行下令
     */
    void execute();

    /**
     * 打消下令
     */
    void undo();
}

3、建立电灯的开启、关闭下令类,实现下令接口

public class LightOnCommand implements Command {
    private LightReceiver lightReceiver;

    public LightOnCommand(LightReceiver lightReceiver) {
        this.lightReceiver = lightReceiver;
    }

    @Override
    public void execute() {
        lightReceiver.on();
    }

    @Override
    public void undo() {
        lightReceiver.off();
    }
}
public class LightOffCommand implements Command {
    private LightReceiver lightReceiver;

    public LightOffCommand(LightReceiver lightReceiver) {
        this.lightReceiver = lightReceiver;
    }

    @Override
    public void execute() {
        lightReceiver.off();
    }

    @Override
    public void undo() {
        lightReceiver.on();
    }
}

4、建立空的下令类,用于初始化按钮

public class NullCommand implements Command {
    @Override
    public void execute() { }

    @Override
    public void undo() { }
}

5、建立下令挪用者

public class RemoteController {
    /**
     * 操作工具的个数
     */
    private static final int COUNT = 5;
    /**
     * 开启下令组
     */
    Command[] onCommands;
    /**
     * 关闭下令组
     */
    Command[] offCommands;
    /**
     * 执行打消的下令
     */
    Command undoCommand;

    /**
     * 初始化
     */
    public RemoteController() {
        onCommands = new Command[COUNT];
        offCommands = new Command[COUNT];
        for (int i = 0; i < COUNT; i++) {
            onCommands[i] = new NullCommand();
            offCommands[i] = new NullCommand();
        }
    }

    /**
     * 设置按钮
     */
    public void setCommand(int no, Command onCommand, Command offCommand) {
        onCommands[no] = onCommand;
        offCommands[no] = offCommand;
    }

    /**
     * 按下开按钮
     */
    public void pressOnButton(int no) {
        onCommands[no].execute();
        //纪录按钮,以便打消
        undoCommand = onCommands[no];
    }

    /**
     * 按下关按钮
     */
    public void pressOffButton(int no) {
        offCommands[no].execute();
        //纪录按钮,以便打消
        undoCommand = offCommands[no];
    }

    /**
     * 按下打消按钮
     */
    public void pressUndoButton(int no) {
        if (undoCommand != null) {
            undoCommand.undo();
        }
    }
}

6、测试类

public class Client {
    @Test
    public void testLight() {
        //建立下令吸收者
        LightReceiver lightReceiver = new LightReceiver();
        //建立电灯的一组操作(开和关)
        LightOnCommand lightOnCommand = new LightOnCommand(lightReceiver);
        LightOffCommand lightOffCommand = new LightOffCommand(lightReceiver);
        //建立下令挪用者
        RemoteController remoteController = new RemoteController();
        //设置下令
        remoteController.setCommand(0, lightOnCommand, lightOffCommand);
        //执行下令
        System.out.println("----按下开灯按钮----");
        remoteController.pressOnButton(0);
        System.out.println("----按下关灯按钮----");
        remoteController.pressOffButton(0);
        System.out.println("----按下打消按钮----");
        remoteController.pressUndoButton(0);
    }
}

7、运行效果

----按下开灯按钮----
电灯打开了
----按下关灯按钮----
电灯关闭了
----按下打消按钮----
电灯打开了

8、若是再添加一个电视机,不需要改动任何已有的代码,添加 TvReceiverTvOnCommandTvOffCommand 这几个类即可。

模式剖析

优点:

  • 降低系统的耦合度
  • 新的下令可以很容易的加入到系统中
  • 容易设计一个下令行列。只要把下令工具放到行列,就可以多线程的执行下令

瑕玷:

  • 可能会导致某些系统有过多的详细下令类。由于针对每一个下令都需要设计一个详细下令类,因此某些系统可能需要大量详细下令类,这将影响下令模式的使用。

适用环境:

  • 系统需要将请求挪用者和请求吸收者解耦,使得挪用者和吸收者不直接交互。
  • 系统需要在差别的时间指定请求、将请求排队和执行请求。
  • 系统需要支持下令的打消(Undo)操作和恢复(Redo)操作。
  • 系统需要将一组操作组合在一起,即支持宏下令。

现实应用场景:

  • 界面的一个按钮都是一个下令
  • 模拟CMD(DOS下令)
  • 订单的打消 / 恢复
  • 触发 - 反馈机制

在 JdbcTemplate 中的应用

在 Spring 的 JdbcTemplate 这个类中有 query() 方式,query() 方式中界说了一个内部类 QueryStatementCallback,QueryStatementCallback 又实现了 StatementCallback 接口,另外另有其它类实现了该接口,StatementCallback 接口中又有一个抽象方式 doInStatement()。在 execute() 中又挪用了 query()。

将其关系缕一缕就是:

,

诚信在线

诚信在线 www.nzg8.com自与农展馆合作以来,拓展了业务战线,深化了服务体系,整合了群体,在未来的2019年,将能更好地为诚信在线娱乐网的会员提供更优质的服务。

Sunbet声明:该文看法仅代表作者自己,与本平台无关。转载请注明:晋城婚介:设计模式 - 下令模式详解及其在JdbcTemplate中的应用

标签列表

    文章归档

      站点信息

      • 文章总数:465
      • 页面总数:0
      • 分类总数:8
      • 标签总数:804
      • 评论总数:0
      • 浏览总数:13467