您的位置:首页 > 其它

设计模式解密(11)- 命令模式 - 扩展篇(命令队列)

2017-07-19 17:22 465 查看

前言:命令模式内容比较多,这里做了拆分

命令模式基础篇 :http://www.cnblogs.com/JsonShare/p/7202133.html

命令模式扩展篇 - 宏命令:http://www.cnblogs.com/JsonShare/p/7206395.html

命令模式扩展篇 - 撤销命令:http://www.cnblogs.com/JsonShare/p/7206513.html

命令模式扩展篇 - 命令队列:http://www.cnblogs.com/JsonShare/p/7206607.html

命令模式扩展篇 - 请求日志:http://www.cnblogs.com/JsonShare/p/7206665.html

3、命令队列

有时候我们需要将多个请求排队,当一个请求发送者发送一个请求时,将不止一个请求接收者产生响应,这些请求接收者将逐个执行业务方法,完成对请求的处理。此时,我们可以通过命令队列来实现。

命令队列的实现方法有多种形式,其中最常用、灵活性最好的一种方式是增加一个CommandQueue类,由该类来负责存储多个命令对象,而不同的命令对象可以对应不同的请求接收者;

CommandQueue类的典型代码如下所示:

public class CommandQueue {
//定义一个ArrayList来存储命令队列
private ArrayList<Command> commands = new ArrayList<Command>();

public void addCommand(Command command) {
commands.add(command);
}

public void removeCommand(Command command) {
commands.remove(command);
}

//循环调用每一个命令对象的execute()方法
public void execute() {
for (Object command : commands) {
((Command)command).execute();
}
}
}


请求发送者类Invoker也要针对CommandQueue编程,代码修改如下:

public class Invoker {
private CommandQueue commandQueue; //维持一个CommandQueue对象的引用

//构造注入
public Invoker(CommandQueue commandQueue) {
this. commandQueue = commandQueue;
}

//设值注入
public void setCommandQueue(CommandQueue commandQueue) {
this.commandQueue = commandQueue;
}

//调用CommandQueue类的execute()方法
public void call() {
commandQueue.execute();
}
}


下面实例讲解:

package com.designpattern.Command.extend.CommandQueue;
/**
* 抽象命令角色类
* @author Json
*/
public interface Command {
/**
* 执行方法
*/
void execute();
}


package com.designpattern.Command.extend.CommandQueue;
/**
* 接收者角色类 - Java工程师
* @author Json
*/
public class JavaCoder {
/**
* 真正执行命令相应的操作
*/
public void work(String task){
System.out.println("java工程师要完成【"+task+"】");
}
}


package com.designpattern.Command.extend.CommandQueue;
/**
* 接收者角色类 - H5工程师
* @author Json
*/
public class H5Coder {
/**
* 真正执行命令相应的操作
*/
public void work(String task){
System.out.println("H5工程师要完成【"+task+"】");
}
}


package com.designpattern.Command.extend.CommandQueue;
/**
* 具体命令 -- Java工程师执行任务
* @author Json
*/
public class JavaCommand implements Command{
//持有相应的接收者对象
private JavaCoder javaCoder;
//具体任务
private String task;
/**
* 构造方法
*/
public JavaCommand(JavaCoder javaCoder,String task){
this.javaCoder = javaCoder;
this.task = task;
}

@Override
public void execute() {
//通常会转调接收者对象的相应方法,让接收者来真正执行功能
javaCoder.work(this.task);
}
}


package com.designpattern.Command.extend.CommandQueue;
/**
* 具体命令 -- H5工程师执行任务
* @author Json
*/
public class H5Command implements Command{
//持有相应的接收者对象
private H5Coder h5Coder;
//具体任务
private String task;
/**
* 构造方法
*/
public H5Command(H5Coder h5Coder,String task){
this.h5Coder = h5Coder;
this.task = task;
}

@Override
public void execute() {
//通常会转调接收者对象的相应方法,让接收者来真正执行功能
h5Coder.work(this.task);
}
}


package com.designpattern.Command.extend.CommandQueue;

import java.util.ArrayList;

/**
* CommandQueue命令队列类
* @author Json
*/
public class CommandQueue {
//定义一个ArrayList来存储命令队列
private ArrayList<Command> commands = new ArrayList<Command>();

public void addCommand(Command command) {
commands.add(command);
}

public void removeCommand(Command command) {
commands.remove(command);
}

//循环调用每一个命令对象的execute()方法
public void execute() {
for(Command command : commands) {
command.execute();
}
}
}


package com.designpattern.Command.extend.CommandQueue;
/**
* 请求发送者类Manager针对CommandQueue编程
* @author Json
*/
public class Manager {
private CommandQueue commandQueue; //维持一个CommandQueue对象的引用

//构造注入
public Manager(CommandQueue commandQueue) {
this. commandQueue = commandQueue;
}

//设值注入
public void setCommandQueue(CommandQueue commandQueue) {
this.commandQueue = commandQueue;
}

//调用CommandQueue类的execute()方法
public void call() {
commandQueue.execute();
}
}


测试:

package com.designpattern.Command.extend.CommandQueue;
/**
*
* @author Json
*/
public class Client {
public static void main(String[] args) {
//创建接收者
JavaCoder javaCoder = new JavaCoder();
H5Coder h5Coder = new H5Coder();
//创建命令对象
JavaCommand javaCommand = new JavaCommand(javaCoder,"登录模块的后台代码");
H5Command h5Command = new H5Command(h5Coder,"登录模块的前台代码");
//创建命令对象队列
CommandQueue commandqueue = new CommandQueue();
commandqueue.addCommand(javaCommand);
commandqueue.addCommand(h5Command);
//创建请求者,把命令对象设置进去
Manager manager = new Manager(commandqueue);
//执行方法
manager.call();
}
}


结果:

java工程师要完成【登录模块的后台代码】
H5工程师要完成【登录模块的前台代码】


上面简单只是实现,旨在了解命令队列的结构:

当一个发送者发送请求后,将有一系列接收者对请求作出响应,命令队列可以用于设计批处理应用程序,如果请求接收者的接收次序没有严格的先后次序,我们还可以使用多线程技术来并发调用命令对象的execute()方法,从而提高程序的执行效率。(注:例子没使用多线程,请自行修改代码!!!)

PS:源码地址 https://github.com/JsonShare/DesignPattern/tree/master

PS:原文地址 http://www.cnblogs.com/JsonShare/p/7206607.html

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: