在一个系统中,一个请求可以被多个对象所处理,职责链通过类似链表的方式将多个处理对象连接在一起,客户端沿着自定义的顺序传递请求。
职责链模式降低了请求的发送端和接收端之间的耦合,使多个对象都有机会处理这个请求
。
0x00 组成部分
- Handler:抽象处理者,声明处理请求的方法,同时
持有下一个处理者的引用
。 - ConcreteHandler:具体处理者,通常有多个,实现了处理请求的方法,也可以选择性的
处理部分请求
,再传递给下一个处理者继续处理。 - Client:客户端负责创建具体的链。
架构UML图如下。
0x01 示例代码
package com.kkk.pattern.chain;
/**
* 官员接口,充当抽象请求处理者。
* Created by z3jjlzt on 2018/1/11.
*/
public abstract class Official {
protected Official successor;
public void setSuccessor(Official successor) {
this.successor = successor;
}
//处理请求
public abstract void handleReq(int level);
}
/**
* 县令,充当具体处理者。
* Created by z3jjlzt on 2018/1/11.
*/
public class Magistrate extends Official{
@Override
public void handleReq(int level) {
if (level <= Lawsuit.LEVEL_1) {
System.out.println("本县令又可以受贿了,好开心!!!");
} else {
System.out.println("这么大的案件,我可不敢自己管,感觉交给上司!!!");
successor.handleReq(level);
}
}
}
/**
* 总督,充当具体处理者。
* Created by z3jjlzt on 2018/1/11.
*/
public class Governor extends Official {
@Override
public void handleReq(int level) {
if (level <= Lawsuit.LEVEL_2) {
System.out.println("本总督好想处理大案件啊,可是却天天处理这些个破案件,真浪费了我的才华!!!");
} else {
System.out.println("好想自己处理啊,可是我没权利管,好可惜。。。");
successor.handleReq(level);
}
}
}
/**
* 丞相,充当具体处理者。
* Created by z3jjlzt on 2018/1/11.
*/
public class PrimeMinister extends Official {
@Override
public void handleReq(int level) {
if (level <= Lawsuit.LEVEL_3) {
System.out.println("本相今天判他个100年!!!");
} else {
System.out.println("泱泱大国可不能毁在我手里呀,感觉通知圣上!!!");
successor.handleReq(level);
}
}
}
/**
* 皇帝,充当具体处理者。
* Created by z3jjlzt on 2018/1/11.
*/
public class Emperor extends Official {
private Random random = new Random();
//这是个昏君,处理国家大事也看心情。
private int mood;
public int getMood() {
mood = random.nextInt(3);
return mood;
}
@Override
public void handleReq(int level) {
switch (getMood()) {
case 0:
System.out.println("寡人今日心情欠佳,无心理会朝事");
break;
case 1:
System.out.println("容我看看是谁吃了豹子胆,胆敢当卖国贼!!");
break;
default:
System.out.println("陛下在睡觉!!!");
break;
}
}
}
**
* 官司分类.
* Created by z3jjlzt on 2018/1/11.
*/
public class Lawsuit {
public static final int LEVEL_1 = 1;
public static final int LEVEL_2 = 2;
public static final int LEVEL_3 = 3;
public static final int LEVEL_4 = 4;
}
/**
* 客户端,负责创建职责链。
* Created by z3jjlzt on 2018/1/11.
*/
public class Client {
public static void main(String[] args) {
Official o1,o2,o3,o4;
o1 = new Magistrate();
o2 = new Governor();
o3 = new PrimeMinister();
o4 = new Emperor();
o1.setSuccessor(o2);
o2.setSuccessor(o3);
o3.setSuccessor(o4);
o1.handleReq(1);
System.out.println();
o4.handleReq(2);
System.out.println();
o3.handleReq(3);
System.out.println();
o1.handleReq(4);
System.out.println();
o1.handleReq(4);
System.out.println();
o1.handleReq(4);
System.out.println();
o1.handleReq(4);
}
}
随机一个结果:
本县令又可以受贿了,好开心!!!
寡人今日心情欠佳,无心理会朝事
本相今天判他个100年!!!
这么大的案件,我可不敢自己管,感觉交给上司!!!
好想自己处理啊,可是我没权利管,好可惜。。。
泱泱大国可不能毁在我手里呀,感觉通知圣上!!!
容我看看是谁吃了豹子胆,胆敢当卖国贼!!
这么大的案件,我可不敢自己管,感觉交给上司!!!
好想自己处理啊,可是我没权利管,好可惜。。。
泱泱大国可不能毁在我手里呀,感觉通知圣上!!!
寡人今日心情欠佳,无心理会朝事
这么大的案件,我可不敢自己管,感觉交给上司!!!
好想自己处理啊,可是我没权利管,好可惜。。。
泱泱大国可不能毁在我手里呀,感觉通知圣上!!!
陛下在睡觉!!!
这么大的案件,我可不敢自己管,感觉交给上司!!!
好想自己处理啊,可是我没权利管,好可惜。。。
泱泱大国可不能毁在我手里呀,感觉通知圣上!!!
寡人今日心情欠佳,无心理会朝事
0xff 总结
- 优点:无需知道请求具体由哪个处理者处理,新增处理者灵活,符合开闭原则。
- 缺点:请求不一定会被处理,如果客户端建立职责链不当,会造成死循环。
- 适用场景:请求的处理者在运行时才确定,在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。