• java23种设计模式之十:责任链模式


      最近在学习netty中发现其中用到了责任链模式,然后结合自己在写代码中遇到了大量写if...else的情况,决定学习一下责任链模式。

    一.什么样的场景下会选择用责任链模式

      我们在进行业务逻辑判断时,需要根据传入参数类型的不同做出不同的处理,如果在传入的参数类型相对较少的情况时,可以用if...else来做判断,这样的确是没有什么问题的,但是如果后期由于业务系统的扩展,导致参数类型会随之延伸出很多种不同的处理,这时就需要用责任链模式来抒代码重构,这样会让代码封装的更好、更简洁,阅读性更强,后期如果增加了新的处理场景,只需要增加新的类就行,不会对原代码有很大的改动。

    责任链模式的使用,会让方法的调用像递归一样的调用向后传递,如果传入的参数类型符合第1个handler处理的定义,那么就由第1个handler进行处理,如果不能处理,那就交由后续的handler进行处理。

    大量的写if...else是可以解决问题,但个人认为写多了,这样的if...else就像一面墙一样,在等着请求类型的不同来选择不同的方法进行处理,而责任链是一条线一样的处理模式,能处理就由当前的处理,不能处理则由后面的handler处理。

    二.责任链模式的编写

      1.抽象1个总的handler

      2.编写3个实现类来实现handler

      3.请求类

      4.客户端测试类

    /**
     * 处理机器人请求
     *     
     * @author    pengbo.zhao
     * @data 2019年12月7日 下午1:51:17
     */
    public abstract class Handler {
        
        public final static String REQUEST_TYPE_ORDER = "order";    //订单处理
        public final static String REQUEST_TYPE_HOT = "hot";        //热点问处理
        public final static String REQUEST_TYPE_HIS = "his";        //历史记录处理
        
        private String type;
        
        private Handler netxtHandler;
        
        public Handler(String type){
            this.type = type;
        }
        
        public final void handlerChain(Request request){
            if(request.getName().equals(this.type)){
                this.handler(request);
            }else{
                if(this.netxtHandler !=null){
                    this.netxtHandler.handlerChain(request);//递归的调用下一个实现handler类的这个方法
                }else{
                    //需要根据业务做其它的处理
                    System.out.println("需要做其它的处理。。。。。。");
                }
            }
        }
        
        public void nextHandler(Handler handler){//设置下一个处理的handler
            this.netxtHandler = handler;
        }
        
        protected abstract void handler(Request request);//实现类重写
    }
    import java.util.Map.Entry;
    
    /**
     * 订单处理
     *     
     * @author    pengbo.zhao
     * @data 2019年12月7日 下午2:13:48
     */
    public class OrderHandler extends Handler{
    
        public OrderHandler(String type) {//子类在继承父类时,虚拟机会先加载父类的属性,先将父类的加载完毕后才能让子类加载,当加载到这里时子类会将传入的参数传递给父类,让父类先加载完成,然后才能加载子类,否则父类不能完全加载
            super(Handler.REQUEST_TYPE_ORDER);
        }
    
        @Override
        protected void handler(Request request) {
            System.err.println("OrderHandler...........");
            for (Entry<String, String> entry : request.getParamterMap().entrySet()) {
                System.out.println("key = "+entry.getKey() +" map = "+entry.getValue());
            }
        }
    
    }
    public class HisHandler extends Handler{
    
        public HisHandler(String type) {
            super(Handler.REQUEST_TYPE_HIS);
        }
    
        @Override
        protected void handler(Request request) {
            System.err.println("HisHandler...........");
            for (Entry<String, String> entry : request.getParamterMap().entrySet()) {
                System.out.println("key = "+entry.getKey() +" map = "+entry.getValue());
            }
        }
    
    }
    public class HotHandler extends Handler{
    
        public HotHandler(String type) {
            super(Handler.REQUEST_TYPE_HOT);
        }
    
        @Override
        protected void handler(Request request) {
            System.err.println("HotHandler...........");
            for(Entry<String, String> entry :request.getParamterMap().entrySet()){
                System.out.println("key = "+entry.getKey() +" value = "+entry.getValue());
            }
        }
    
    }

    请求类

    public class Request {
        
        public Request(String name, Map<String, String> paramterMap) {
            this.name = name;
            this.paramterMap = paramterMap;
        }
        private String name;
        private Map<String,String> paramterMap;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Map<String, String> getParamterMap() {
            return paramterMap;
        }
        public void setParamterMap(Map<String, String> paramterMap) {
            this.paramterMap = paramterMap;
        }
        
    }

    测试类

    public class Test {
        public static void main(String[] args) {
            String types [] = {"order","hot","his"};
            Map<String,String> paramMap = new HashMap<>();
            paramMap.put("key_1", "value_1");
            paramMap.put("key_2", "value_2");
            Request request = new Request(types[new Random().nextInt(3)],paramMap);
            
            Handler orderHandler = new OrderHandler(Handler.REQUEST_TYPE_ORDER);
            Handler hotHandler = new HotHandler(Handler.REQUEST_TYPE_HOT);
            Handler hishandler = new HisHandler(Handler.REQUEST_TYPE_HIS);
            
            orderHandler.nextHandler(hotHandler);
            hotHandler.nextHandler(hishandler);
            
            orderHandler.handlerChain(request);
            
        }
    }
  • 相关阅读:
    浏览器输入一个url到整个页面显示出来经历了哪些过程?
    ajax
    为什么JS是单线程?JS中的Event Loop(事件循环)?JS如何实现异步?setimeout?
    jQuery中ready方法的实现
    this+call、apply、bind的区别与使用
    内存泄漏、垃圾回收机制、哪些情况会导致内存泄漏
    浏览器同源策略和跨域方法
    node.js
    JS原型、原型链、构造函数、实例与继承
    JS常用操作节点的方法
  • 原文地址:https://www.cnblogs.com/MrRightZhao/p/12001911.html
Copyright © 2020-2023  润新知