Chain of Responsibility(责任链)
一、意图
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
二、结构
责任链模式的结构图如图7-38所示。
其中:
• Handler定义一个处理请求的接口;(可选)实现后继链。
• ConcreteHandler处理它所负责的请求;可访问它的后继者;如果可处理该请求,就处理它,否则将该请求转发给后继者。
• Client向链上的具体处理者(ConcreteHandler)对象提交请求。
三、适用性
Chain of Responsibility模式适用于以下条件:
• 有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
• 想在不明确指定接收者的情况下向多个对象中的一个提交一个请求。
• 可处理一个请求的对象集合应被动态指定。
四、实现
学校规定参加校招的同学必须要请假,且要有相关人员的签字,三天以下需辅导员签字、三到七天需要系主任签字,一个星期以上需要院长签字,更多的则需要校长签字!
上图将学生、辅导员、系主任、院长、校长组成了一个简单的链,在这个链上,学生是申请者,其余的都是请求处理者。对于这种将请求一级一级地往上传递直到请求被处理的设计模式就是职责链模式。
首先 创建离开节点
。
class LeaveNode {
private int number; //请假天数
private String person; //请假人
public LeaveNode(String person,int number){
this.person = person;
this.number = number;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getPerson() {
return person;
}
public void setPerson(String person) {
this.person = person;
}
}
然后 创建领导人抽象类,并分别用辅导员、系主任、院长、校长去继承
。
abstract class Leader {
public String name; //姓名
protected Leader successor; //后继者
public Leader(String name){
this.name = name;
}
public void setSuccessor(Leader successor) {
this.successor = successor;
}
public abstract void handleRequest(LeaveNode LeaveNode);
}
class Instructor extends Leader{
public Instructor(String name){
super(name);
}
public void handleRequest(LeaveNode LeaveNode) {
if(LeaveNode.getNumber() <= 3){ //小于3天辅导员审批
System.out.println(name + "审批" +LeaveNode.getPerson() + "同学的请假条,请假天数为" + LeaveNode.getNumber() + "天。");
}
else{ //否则传递给系主任
if(this.successor != null){
this.successor.handleRequest(LeaveNode);
}
}
}
}
class DepartmentHead extends Leader{
public DepartmentHead(String name) {
super(name);
}
public void handleRequest(LeaveNode LeaveNode) {
if(LeaveNode.getNumber() <= 7){ //小于7天系主任审批
System.out.println(name + "审批" +LeaveNode.getPerson() + "同学的请假条,请假天数为" + LeaveNode.getNumber() + "天。");
}
else{ //否则传递给院长
if(this.successor != null){
this.successor.handleRequest(LeaveNode);
}
}
}
}
class Dean extends Leader{
public Dean(String name) {
super(name);
}
public void handleRequest(LeaveNode LeaveNode) {
if(LeaveNode.getNumber() <= 10){ //小于10天院长审批
System.out.println(name + "审批" +LeaveNode.getPerson() + "同学的请假条,请假天数为" + LeaveNode.getNumber() + "天。");
}
else{ //否则传递给校长
if(this.successor != null){
this.successor.handleRequest(LeaveNode);
}
}
}
}
class President extends Leader{
public President(String name) {
super(name);
}
public void handleRequest(LeaveNode LeaveNode) {
if(LeaveNode.getNumber() <= 15){ //小于15天校长长审批
System.out.println(name + "审批" +LeaveNode.getPerson() + "同学的请假条,请假天数为" + LeaveNode.getNumber() + "天。");
}
else{ //否则不允批准
System.out.println(LeaveNode.getPerson()+"同学"+"请假天天超过15天,不批准...");
}
}
}
最后 测试一下
。
public class ChainOfResponsibility {
public static void main(String[] args) {
// TODO Auto-generated method stub
Leader instructor = new Instructor("刘辅导员"); //辅导员
Leader departmentHead = new DepartmentHead("王主任"); //系主任
Leader dean = new Dean("张院长"); //院长
Leader president = new President("李校长"); //校长
instructor.setSuccessor(departmentHead); //辅导员的后续者是系主任
departmentHead.setSuccessor(dean); //系主任的后续者是院长
dean.setSuccessor(president); //院长的后续者是校长
//请假3天的请假条
LeaveNode leaveNode1 = new LeaveNode("张三", 3);
instructor.handleRequest(leaveNode1);
//请假5天的请假条
LeaveNode leaveNode2 = new LeaveNode("李四", 5);
instructor.handleRequest(leaveNode2);
//请假9天的请假条
LeaveNode leaveNode3 = new LeaveNode("王五", 9);
instructor.handleRequest(leaveNode3);
//请假12天的请假条
LeaveNode leaveNode4 = new LeaveNode("赵六", 12);
instructor.handleRequest(leaveNode4);
//请假18天的请假条
LeaveNode leaveNode5 = new LeaveNode("孙七", 18);
instructor.handleRequest(leaveNode5);
}
}
运行结果:
五、小结
纯的与不纯的责任链模式:
(1)纯的责任链模式要求处理者对象只能在两个行为中选择一个:一是承担责任,二是把责任推给下家,不允许出现某一个具体处理者对象在承担了一部分责任后又把责任向下传的情况。
(2)在纯的责任链模式里面,请求必须被某一个处理者对象所接收;在不纯的责任链模式里面,一个请求可以最终不被任何接收端对象所接收。