zoukankan      html  css  js  c++  java
  • 设计模式解密(11)- 命令模式

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

    命令模式基础篇 :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

      

  • 相关阅读:
    C#表示空字符串
    char varchar nvarchar区别
    WCF 服务器端 上传图片
    各种算法时间复杂度
    ADO.net 对象
    走出浮躁的泥沼
    英语学习
    前端获取GridView和ASPxGridView单元格中的值
    【dfs+染色】【HDOJ】5652 India and China Origins
    【模拟】【codeforces】599B Spongebob and Joke
  • 原文地址:https://www.cnblogs.com/JsonShare/p/7206607.html
Copyright © 2011-2022 走看看