• java设计模式之命令


    命令模式将请求封装成一系列对象,对象里包含指令和数据。

    在分布式架构中,master需要给worker分发任务,worker完成后需要把任务处理结果返回给master。

    master/worker之间的信息交互会有很多不同的指令和数据,这种不同消息的实现就可以采用命令模式。

    我们首先定义一个命令对象

    一、命令模式同步实现

    public class Command implements Serializable,Cloneable {
        private static AtomicLong idGenerator=new AtomicLong(1L);
        private Long id;
        private String request;
        private String response;
    
        public Command( String content) {
            this.id = idGenerator.getAndIncrement();
            this.request = content;
        }
    
        public String getResponse() {
            return response;
        }
    
        public void setResponse(String response) {
            this.response = response;
        }
    
        protected Command clone()  {
            try {
                return (Command) super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        @Override
        public String toString() {
            return "Command{" +
                    "id=" + id +
                    ", request='" + request + '\'' +
                    ", response='" + response + '\'' +
                    '}';
        }
    }

    然后定义一个master,master负责向worker发送命令

    public class Master {
        void dispatch(Worker worker,Command command){
            System.out.println("dispatch a command:"+command +"to "+worker.getClass().getSimpleName());
            Command response = worker.process(command);
            System.out.println("receive a command"+response);
        }
    
        public static void main(String[] args) {
            Command command1 = new Command("hello,python!");
            Command command2 = new Command("hello,java!");
            Master master = new Master();
            Worker worker1 = new Worker1();
            Worker worker2 = new Worker2();
            master.dispatch(worker1,command1);
            master.dispatch(worker2,command2);
        }
    }

    定义一个worker接口,用于处理命令,并返回任务的结果

    public interface Worker {
        Command process(Command command);
    }
    
    public class Worker1 implements Worker {
        @Override
        public Command process(Command command) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Command clone = command.clone();
            clone.setResponse("worker1  ok");
            return clone;
        }
    }
    
    public class Worker2 implements Worker {
        @Override
        public Command process(Command command) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Command clone = command.clone();
            clone.setResponse("worker2  ok");
            return clone;
        }
    }

    执行master,输出:

    dispatch a command:Command{id=1, request='hello,python!', response='null'}to Worker1
    receive a commandCommand{id=1, request='hello,python!', response='worker1  ok'}
    dispatch a command:Command{id=2, request='hello,java!', response='null'}to Worker2
    receive a commandCommand{id=2, request='hello,java!', response='worker2  ok'}

     二、命令模式异步实现

    其实分布式系统中,更常见的实现是异步io,我们给Worker接口添加一个异步处理方法

    public interface Worker {
        /**
         * 同步处理
         * @param command
         * @return
         */
        Command process(Command command);
    
        /**
         * 异步处理
         * @param command
         */
        void asyncProcess(Command command);
    }

    定义一个实现了Worker接口的实现类

    public class AsyncWorker implements Worker {
        @Override
        public Command process(Command command) {
            return null;
        }
    
        @Override
        public void asyncProcess(Command command){
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Command clone = command.clone();
            Long id = clone.getId();
            clone.setResponse("AsyncWorker ok");
            ResponseFuture future = ResponseFuture.getFuture(id);
            future.putResponse(clone);
        }
    }

    因为是异步处理,我们定义一个Future类

    /**
     * 任务结果future类
     */
    public class ResponseFuture {
        private static final Map<Long,ResponseFuture> futures=new ConcurrentHashMap<>(256);
        private long requestId;
        private CountDownLatch latch=new CountDownLatch(1);
        private Command response;
        private final InvokeCallback invokeCallback;
    
        public ResponseFuture(long requestId,  InvokeCallback invokeCallback) {
            this.requestId = requestId;
            this.invokeCallback = invokeCallback;
            futures.put(requestId, this);
        }
    
        public void executeInvokeCallback() {
            if (invokeCallback != null) {
                invokeCallback.operationComplete(this);
            }
        }
    
        public void putResponse(final Command responseCommand) {
            this.response = responseCommand;
            this.latch.countDown();
            futures.remove(requestId);
        }
    
        public Command getResponseCommand() {
            return response;
        }
    
        public static ResponseFuture getFuture(long requestId) {
            return futures.get(requestId);
        }
    }

    定义一个回调接口,用于获得结果后的回调

    /**
     * 回调接口
     */
    public interface InvokeCallback {
        void operationComplete(final ResponseFuture responseFuture);
    }

    因为需要异步获取结果,我们对command类进行了扩展

    public class Command implements Serializable,Cloneable {
        private static AtomicLong idGenerator=new AtomicLong(1L);
        private Long id;
        private String request;
        private String response;
    
        public Command( String content) {
            this.id = idGenerator.getAndIncrement();
            this.request = content;
        }
    
        public Long getId() {
            return id;
        }
    
        public String getResponse() {
            return response;
        }
    
        public void setResponse(String response) {
            this.response = response;
        }
    
        protected Command clone()  {
            try {
                return (Command) super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        @Override
        public String toString() {
            return "Command{" +
                    "id=" + id +
                    ", request='" + request + '\'' +
                    ", response='" + response + '\'' +
                    '}';
        }
    }

    master发生异步请求

    public class Master {
    //    void dispatch(Worker worker, Command command) {
    //        System.out.println("dispatch a command:" + command + "to " + worker.getClass().getSimpleName());
    //        Command response = worker.process(command);
    //        System.out.println("receive a command" + response);
    //    }
    
        void dispatchAsync(Worker worker, Command command, final InvokeCallback invokeCallback) {
            System.out.println("dispatch a command:" + command + "to " + worker.getClass().getSimpleName());
            Long requestId = command.getId();
            ResponseFuture responseFuture = new ResponseFuture(requestId, invokeCallback);
            worker.asyncProcess(command);
            responseFuture.executeInvokeCallback();
    
    
        }
    
        public static void main(String[] args) {
            Master master = new Master();
    //        Command command1 = new Command("hello,sync!");
    //        Worker worker1 = new SyncWorker();
    //        System.out.println("dispatch Sync");
    //        master.dispatch(worker1, command1);
            Command command2 = new Command("hello,async!");
            Worker worker2 = new AsyncWorker();
            System.out.println("dispatch ASync");
            master.dispatchAsync(worker2, command2, new InvokeCallback() {
                @Override
                public void operationComplete(ResponseFuture responseFuture) {
                    Command responseCommand = responseFuture.getResponseCommand();
                    System.out.println(responseCommand);
                }
            });
        }
    }

    输出:

    dispatch ASync
    dispatch a command:Command{id=1, request='hello,async!', response='null'}to AsyncWorker
    Command{id=1, request='hello,async!', response='AsyncWorker ok'}

    上面的实现是分布式架构的一种简化,以方便在单机进行演示。

    实际的分布式架构中,master拿不到worker对象,worker也不可能拿到Future对象,异步消息的传递一般是基于异步io框架(比如netty)的channel来实现的。

    netty不是我们本文讨论的重点,这里就不做更多的描述了。

  • 相关阅读:
    EasyPR--开发详解(2)车牌定位
    EasyPR--中文开源车牌识别系统 开发详解(1)
    EasyPR--一个开源的中文车牌识别系统
    Ajax异步请求原理的分析
    ajax同步
    ajax解决跨域
    ajax及其工作原理
    python编码设置
    python编译hello
    WinForm通过操作注册表实现限制软件使用次数的方法
  • 原文地址:https://www.cnblogs.com/wangbin2188/p/15842686.html
Copyright © 2020-2023  润新知