《一天一模式》— 责任链模式

1、责任链模式的概念

责任链模式是一种对象的行为模式。在责任链模式里,不少对象由每个对象对其下家的引用而链接起来造成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪个对象最终处理这个请求,这使得系统能够在不影响客户端的状况下动态地从新组织和分配责任。java

2、何时使用责任链模式

根据概念理解,责任链模式是一种能够处理一次请求流的一种模式,相似业务工做流程,并且责任链能够动态的调整流程中的各个环节。设计模式

也就是说,若是业务里有这种须要逐级处理的业务,但是尝试使用责任链模式。测试

我在项目中,通常须要逐级作业务判断的时候会使用工做流模式,例如:优化

http请求拦截器,先判断HttpHeader的协议是否正确,在判断登陆信息是否正确,在判断请求内容是否正确等,这几步判断就能够用责任链模式实现;this

从代码结构角度,能够解决嵌套if的问题,例如:spa

if (验证协议) {
    ....
    if (验证鉴权) {
        ....
        if (验证数据) {
            ....
        }
    }
}

能够避免这种嵌套if结构,提高代码的可读性。下面来试着用Java代码实现责任链模式。设计

3、怎么使用责任链模式

3.1 实现方式

就以请求拦截器为例,模拟作一个责任链模式,一共三步验证:code

  • 验证协议是否正确;
  • 验证登陆信息是否正确;
  • 验证请求数据是否正确;

下面是类图和代码:对象

// 责任链模式的抽象类
public abstract class Validator {

    // 设置责任链的下一个环节
    private Validator next;

    public Validator setNext(Validator next) {
        this.next = next;
        // 返回下一个环节,作到链式设置
        return next;
    }

    // 开始责任链的处理
    public final void handler(List<String> context) {
        if (!resolve(context)) { // 判断处理结果是否失败,若是失败则不向下进行
            fail(context);
        } else if (next != null) { // 若是本环节处理成功,判断是否还有下一环节,若是就,就执行下一个环节的handler
            next.handler(context);
        } else { // 若是处理成功,切没有下一个环节了,责任链结束
            success(context);
        }
    }

    // 具体处理业务的方法,定义一个抽象方法等待被子类实现(相似模板方法模式)
    protected abstract boolean resolve(List<String> context);

    // 成功经过的处理
    protected void success(List<String> context) {
        System.out.println("验证经过。");
    }

    // 未成功经过的处理
    protected void fail(List<String> context) {
        System.out.println("验证失败。");
    }

}

// 验证鉴权的处理类
public class AuthValidator extends Validator {

    public boolean resolve(List<String> context) {
        return context.get(1).equals("admin");
    }
}

// 验证协议的处理类
public class ProtocolValidator extends Validator {

    public boolean resolve(List<String> context) {
        return context.get(0).equals("http");
    }
}

// 验证数据的处理类
public class DataSecurityValidator extends Validator {

    public boolean resolve(List<String> context) {
        return context.get(2).equals("hello");
    }
}

上面是责任链模式的类图和代码,从代码上看,抽象类定义了责任链的建立方法,和循环调用方法,但具体的处理,须要有子类的实现(相似模板方法),而后在成功或者失败的时候,进行相关处理,责任链模式的使用方式以下:blog

public class Client {

    public static void main(String[] args) {

        // 由于是测试,因此在此处配置了责任链的关系,正常状况下,Client是不须要知道责任链的配置关系的
        Validator protocolValidator = new ProtocolValidator();
        Validator authValidator = new AuthValidator();
        Validator dataSecurityValidator = new DataSecurityValidator();
        protocolValidator.setNext(authValidator).setNext(dataSecurityValidator);
        // 处理,模拟验证经过
        List<String> params1 = new ArrayList<String>();
        params1.add("http");
        params1.add("admin");
        params1.add("hello");
        protocolValidator.handler(params1);
        // 处理,模拟验证失败
        List<String> params2 = new ArrayList<String>();
        params2.add("http");
        params2.add("ss");
        params2.add("hello");
        protocolValidator.handler(params2);
    }

}

先将几个环节经过setNext创建起关联,而后从某个节点(一般是第一个节点)开始调用handler,进行业务的处理。

以上就是责任链模式的Java代码实现。

3.2 责任链模式的好处

责任链模式的好处以下:

  • 可读性高:将嵌套判断的代码块用面向对象的方式去优化,经过良好的命名起到语义化的效果;
  • 灵活性强:能够随意经过setNext配置各个判断环节的先后关系,而不须要修改代码,嵌套if是作不到的;
  • 扩展性强:如后续有需求变动,能够快读的加入新的责任链环节,而无需修改原有代码,符合开闭原则;

4、总结

责任链模式,面相的业务场景相对比较单一,比较好肯定在什么业务场景下使用。可是实现的代码比起其余的设计模式,稍微复杂了一点,但也比较好理解。

还有就是,责任链模式的一个隐藏的优势是,它弱化了调用者(Client)和处理者(Validator)以前的关联,调用者其实无需知道责任链的每一个环节的关系,只是去调用责任链的hanlder方法便可,这种解除耦合的优势很重要。

以上就是我对责任链模式的一些理解,有不足之处请你们指出,谢谢。

相关文章
相关标签/搜索