责任链模式,当程序需要以不同的方式处理不同的请求且请求类型和顺序未知时,可以将所有的处理方式编织成一个链条,每一个处理算子均可以选择处理或者向下传递。这就是责任链模式。
如下,是一个请假系统
/**
* 员工
* */
public class Employee {
//级别
int type;
//申请假期
public boolean apply(LeaveChain leaveChain,int days){
return leaveChain.approver(this,days);
};
}
/**
* 管理者
* */
public abstract class Administrator extends Employee {
//审批假期
public abstract boolean approver(Employee e,int days);
}
/**
* 普通员工
* */
public class NormalEmployee extends Employee{
//级别
public NormalEmployee(){this.type=0;}
}
/**
* 组长
* */
public class GroupLeader extends Administrator{
//级别
public GroupLeader(){this.type=1;}
@Override
public boolean approver(Employee e,int days) {
if(e.type <= this.type&&days<=5) {
System.out.println("组长给你批过了");
return false;
}
return true;
}
}
/**
* 经理
* */
public class Manager extends Administrator{
//级别
public Manager(){this.type =2;}
@Override
public boolean approver(Employee e,int days) {
if(e.type <= this.type&&days<=10) {
System.out.println("经理给你批过了");
return false;
}
return true;
}
}
/**
* 董事长
* */
public class Boss extends Administrator{
//级别
public Boss(){this.type = 3;}
@Override
public boolean approver(Employee e,int days) {
if(e.type == this.type) {
System.out.println("我是Boss不需要审批");
}else{
System.out.println("Boss给你批过了");
}
return false;
}
}
/**
* 请假链
* */
public class LeaveChain {
//请假链条
LinkedList<Administrator> leaveChain;
public LeaveChain(LinkedList<Administrator> leaveChain){
this.leaveChain = leaveChain;
}
@Override
public boolean approver(Employee e,int days) {
for(Administrator administrator:leaveChain){
if(!administrator.approver(e,days)) return false;
}
return true;
}
}
public class Main {
public static void main(String[] args) {
//生成责任链
LinkedList<Administrator> list = new LinkedList<>();
list.add(new GroupLeader());
list.add(new Manager());
list.add(new Boss());
LeaveChain leaveChain = new LeaveChain(list);
//随机生成员工
Employee[]es=getEmployee(10);
for(int i=0;i<es.length;i++){
int days = (int)(Math.random()*15)+1;
String str ="";
switch (es[i].type){
case 0 :
str = "我是普通员工,";
break;
case 1 :
str = "我是组长,";
break;
case 2:
str = "我是经理,";
break;
case 3:
str = "我是Boss,";
break;
}
str += "我请了"+days+"天假.";
System.out.println(str);
es[i].apply(leaveChain,days);
}
}
public static Employee[] getEmployee(int length){
Employee[] e= new Employee[length];
for(int i =0;i<e.length;i++){
int falg = (int)(Math.random()*4);
switch (falg){
case 0 :
e[i] = new NormalEmployee();
break;
case 1 :
e[i] = new GroupLeader();
break;
case 2:
e[i] = new Manager();
break;
case 3:
e[i] = new Boss();
break;
}
}
return e;
}
}
执行结果:
我是普通员工,我请了6天假.
经理给你批过了
我是Boss,我请了4天假.
我是Boss不需要审批
我是Boss,我请了15天假.
我是Boss不需要审批
我是组长,我请了12天假.
Boss给你批过了
我是组长,我请了4天假.
组长给你批过了
我是普通员工,我请了3天假.
组长给你批过了
我是普通员工,我请了8天假.
经理给你批过了
我是Boss,我请了1天假.
我是Boss不需要审批
我是经理,我请了7天假.
经理给你批过了
我是普通员工,我请了12天假.
Boss给你批过了
说明:如果需要多个责任链与责任链之间的对接,那么让责任链和链内成员统一实现同一个接口,使得责任链本身和责任链内部成员是一样的。
通过往责任链中添加子责任链的方式完成多个责任链的对接。
上述案列让LeaveChain继承Administrator,此时责任链本身也是一个管理者,遍历到子责任链时将执行子责任链的approver()方法然后继续遍历子责任链的内部管理者成员。
直到返回false整条责任链处理完成。