模式概述:
允许你将请求沿着处理者链进行发送。 收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。
使用场景:
1.当程序需要使用不同方式处理不同种类请求, 而且请求类型和顺序预先未知时, 可以使用责任链模式。
2.当必须按顺序执行多个处理者时, 可以使用该模式。
3.如果所需处理者及其顺序必须在运行时进行改变, 可以使用责任链模式。
代码样例:
代码背景: 公司的员工申请岗位晋升,公司设置对应的考核面试;对于中级职位需要依次考核h5、js技能;对应高级职位需要依次考核h5、js、java技能。只有所有考核都通过才能算岗位晋升成功,并对晋升成功的员工进行一定的加薪处理。
/**
* 员工
*/
public class Staff {
private String name;//名称
private String skill;//技能
private long pay;//薪资
public Staff(String name, String skill, long pay) {
this.name = name;
this.skill = skill;
this.pay = pay;
}
public String getSkill() {
return skill;
}
public long getPay(){
return pay;
}
public void setPay(long pay) {
this.pay = pay;
}
@Override
public String toString() {
return "Staff{" +
"name='" + name + '\'' +
", skill='" + skill + '\'' +
", pay='" + pay + '\'' +
'}';
}
/**
* 抽象责任链环节
*/
public abstract class ResponsibilityComponent {
private ResponsibilityComponent next;//每个环节有下个环节的引用,从而形成链
/**
* 设置当前环节的下个环节
*/
public ResponsibilityComponent linkWith(ResponsibilityComponent responsibilityComponent){
next = responsibilityComponent;
return next;
}
public abstract boolean check(Staff staff);
public boolean checkNext(Staff staff){
if(next !=null) return next.check(staff);
return true;
}
}
/**
* 责任链中的一个环节
*/
public class ResponsibilityComponentLevelH5 extends ResponsibilityComponent{
@Override
public boolean check(Staff staff) {
boolean result = true;
if(staff.getSkill().contains("h5")){
System.out.println("H5面试官:精通h5,pass");//request的handle
result = checkNext(staff);//下一个环节handle
if(result) {
System.out.println("H5面试官:薪资再加500");//response的handle
staff.setPay(staff.getPay()+500l);
}
}else{
System.out.println("H5面试官:不会h5,岗位晋升失败");
result = false;
}
return result;
}
}
/**
* 责任链中的一个环节
*/
public class ResponsibilityComponentLevelJs extends ResponsibilityComponent{
@Override
public boolean check(Staff staff) {
boolean result = true;
if(staff.getSkill().contains("js")){
System.out.println("js面试官:精通js,pass");//request的handle
result = checkNext(staff);//下一个环节handle
if(result){
System.out.println("js面试官:薪资再加1000");//response的handle
staff.setPay(staff.getPay()+1000l);
}
}else{
System.out.println("js面试官:不会js,岗位晋升失败");
result = false;
}
return result;
}
}
/**
* 责任链中的一个环节
*/
public class ResponsibilityComponentLevelJava extends ResponsibilityComponent{
@Override
public boolean check(Staff staff) {
boolean result = true;
if(staff.getSkill().contains("java")){
System.out.println("java面试官:精通java,pass");//request的handle
result = checkNext(staff);//下一个环节handle
if(result){
System.out.println("java面试官:薪资再加2000");//response的handle
staff.setPay(staff.getPay()+2000l);
}
}else{
System.out.println("java面试官:不会java,岗位晋升失败");
result = false;
}
return result;
}
}
public class TestChainOfResponsibility {
public static void main(String[] args) {
System.out.println("公司岗位晋升:中级需要经过h5、js的面试;高级需要经过h5、js、java的面试");
//高级工程师晋升责任链
ResponsibilityComponent p7 = new ResponsibilityComponentLevelH5();
p7.linkWith(new ResponsibilityComponentLevelJs()).linkWith(new ResponsibilityComponentLevelJava());
//中级工程晋升责任链
ResponsibilityComponent p5 = new ResponsibilityComponentLevelH5();
p5.linkWith(new ResponsibilityComponentLevelJs());
System.out.println();
System.out.println("张三准备晋升高级工程师:");
Staff zs = new Staff("zs","h5,js,java",5000l);
if(p7.check(zs)) System.out.println(zs.toString());;
System.out.println();
System.out.println("李四准备晋升高级工程师:");
Staff ls = new Staff("ls","h5,js",5000l);
if(p7.check(ls)) System.out.println(ls.toString());;
System.out.println();
System.out.println("王五准备晋升中级工程师:");
Staff ww = new Staff("ww","h5,js,java",3000l);
if(p5.check(ww)) System.out.println(ww.toString());;
}
}
测试结果:
模式对比:
责任链模式与装饰者模式都是使用的递归思想,结构非常相似;责任链是强调顺序执行,且可能随时结束请求的传递,存在有些环节执行不到的情况;装饰者对顺序无特殊要求,无法中断请求,每个装饰者都必须执行来对方法进行增强。