一、概念

责任链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

二、责任链模式的组成结构

抽象处理者角色(Handler): 它定义了一个处理请求的接口。当然对于链子的不同实现,也可以在这个角色中实现后继链。
具体处理者角色(Concrete Handler): 实现抽象角色中定义的接口,并处理它所负责的请求。如果不能处理则访问它的后继者。

类图:

java 责任链源码 java责任链模式实例_java 责任链源码

三、示例代码

应用场景:传入一个字符串,自动识别为日期类型、数字类型还是字符串类型。

抽象处理者角色 – Handler

public abstract class Handler {
    protected Handler nextHandler;
    // 传入一个字符串,最后将其转换为需要的类型
    abstract void transformStr(String string);

    // 指定下一个处理者
    void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }
}

具体处理角色 – DateHandler、NumberHandler、StringHandler

//日期处理
public class DateHandler extends Handler {
    @Override
    void transformStr(String string) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat ("yyyy-MM-dd");
        try {
            simpleDateFormat.parse (string);
            System.out.println ("传入的为日期字符串:"+string);
        } catch (ParseException e) {
            //日期处理类无法处理,转给下一个处理类处理
            nextHandler.transformStr (string);
        }
    }
}
//数字处理
public class NumberHandler extends Handler {
    @Override
    void transformStr(String string) {
        try{
            int num = Integer.parseInt (string);
            System.out.println ("传入的是数字字符串:"+num);
        }catch (Exception e){
            //数字处理类无法处理,转给下一个处理类处理
            nextHandler.transformStr (string);
        }
    }
}
//字符串处理
public class StringHandler extends Handler {
    @Override
    public void transformStr(String string) {
        System.out.println ("传入的为字符串:"+string);
    }
}

测试

public class Main {
    public static void main(String[] args) {
        DateHandler dateHandler = new DateHandler ();
        StringHandler stringHandler = new StringHandler ();
        NumberHandler numberHandler = new NumberHandler ();
        //设置职责链
        dateHandler.setNextHandler (numberHandler);
        numberHandler.setNextHandler (stringHandler);
        //也可通过list设置职责链,遍历执行
        //List<Handler> handlerChain = new ArrayList<> ();

        dateHandler.transformStr ("2018-02-23");
        dateHandler.transformStr ("123");
        dateHandler.transformStr ("jfdskj");
    }
}

输出结果:

java 责任链源码 java责任链模式实例_设计模式_02

四、适用范围

1 ) 有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
2 ) 你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
3 ) 可处理一个请求的对象集合应被动态指定。

五、优点

1、降低耦合度。它将请求的发送者和接收者解耦。
2、简化了对象。使得对象不需要知道链的结构。
3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。