设计模式

小白设计模式:责任链模式

2018-11-18  本文已影响0人  CodeInfo

定义

将多个接收对象(处理者)组成链式结构,按序对输入的信号事件进行处理直到事件被处理。

主要组成

抽象处理者(Handler) : 责任链上每一环的处理对象,抽象处理接口。

具体处理者(concrete Handler) : 实现Handler相关接口,并持有责任链上下一个处理者的引用。对输入的事件进行判断,符合条件则截断事件传递并进行处理,否则将事件接着往下传递。

输入事件(request) : 输入到责任链请求被处理的事件信号

UML类图

image

框架代码:

抽象处理者

public abstract class Handler {
        //下一个处理者引用,末尾位置没有则为null
        Handler nextHandler;
        
        public Handler(Handler nextHandler) {
            this.nextHandler = nextHandler;
        }
        
        public abstract void handRequest(Request request);
    }

具体处理者

//具体处理者1
    public class JsonHandler extends Handler{

        public JsonHandler(Handler nextHandler) {
            super(nextHandler);
        }
    
        @Override
        public void handRequest(Request request) {
            if (request.isJson()) {
                
                //添加事件处理代码
                System.out.println( "JsonHandler");
                
            } else if (nextHandler != null) {
                
                //调用下一个处理者处理事件
                nextHandler.handRequest(request);
                
            }
        }
    }
    
//具体处理者2
    public class XmlHandler extends Handler{

        public XmlHandler(Handler nextHandler) {
            super(nextHandler);
        }
    
        @Override
        public void handRequest(Request request) {
            if (request.isXml()) {
                
                //添加事件处理代码
                System.out.println( "XmlHandler");
                
            } else if (nextHandler != null) {
                
                //调用下一个处理者处理事件
                nextHandler.handRequest(request);
                
            }
        }
    }
    
//具体处理者3
    public class StringHandler extends Handler{

        public StringHandler(Handler nextHandler) {
            super(nextHandler);
        }
    
        @Override
        public void handRequest(Request request) {
            if (request.isString()) {
                
                //添加事件处理代码
                System.out.println( "StringHandler");
                
            } else if (nextHandler != null) {
                
                //调用下一个处理者处理事件
                nextHandler.handRequest(request);
                
            }
        }
    }

模拟事件对象

public class Request {
    
        boolean isJson = false;
        boolean isXml = false;
        boolean isString = false;
        
        public Request(boolean isJson, boolean isXml, boolean isString) {
            
            this.isJson = isJson;
            this.isXml = isXml;
            this.isString = isString;
            
        }
        
        public boolean isJson() {
            return isJson;
        }
        
        public boolean isXml() {
            return isXml;
        }
        
        public boolean isString() {
            return isString;
        }
    
    }

简单测试代码:

public class Main {
    public static void main(String[] args){
        Handler handler = new JsonHandler(new XmlHandler(new StringHandler(null)));
        handler.handRequest(new Request(false, false, true));
    }
}

打印:
StringHandler

该简单测试用例的链条组成顺序为:

JsonHandler --> XmlHandler --> StringHandler

则事件的传递与处理方向同样安装该顺序来:
JsonHandler.handRequest --> XmlHandler.handRequest --> StringHandler.handRequest

总结

优点

将事件的发送者与接受处理者解耦。(这边可以这么理解,假设不使用责任链,如果有5种事件对应可以处理的5个处理者,则调用方需要创建这5个处理者,并且一一调用各自的处理事件的方法。但是如果使用责任链,调用者不用关心有多少个处理者,因为提供给调用者的就只是责任链上的第一个元素,提供的是接口,相当于将整个责任链看做一个对象以接口的形式传递给调用者,调用者只需要调用这个对象的处理接口即可。)

简化了单个处理者处理逻辑,不需要判断并处理各种事件类型。处理者处不需要知道链的整体结构(但需要知道下一个处理者),只需要判断处理传递给自己的事件,如果无法处理则传递给下一个处理者。

可以动态的改变、调整责任链的成员组成,达到增加/删除或改变处理者的处理顺序。

缺点

可能存在事件传递到最后都没有被处理的情况(既是优点也是缺点)

效率上的影响,毕竟比所有处理都写在一起相比多了创建各个对象的消耗等

不容易观察运行时特征,排查问题相对麻烦

使用场景

多个对象都需要判断处理同一种事件类型时,例如android系统中事件分发等,这种链条式处理消息的场景。

扫码微信,关注公众号

image
上一篇下一篇

猜你喜欢

热点阅读