1.定义:是多个对象都能够处理请求,避免请求发送者和处理者之间的耦合。将请求处理对象连成一条链,请求将会沿着该链传递并最终被处理。比如java web中无状态的javabean,该javabean有客户端发起经过多层处理后插入到数据库。又比如javaweb中的过滤器
2.UML
3.涉及角色
1.抽象请求处理角色:一般为抽象类,定义类处理请求的行为,该类持有自己的实例。该实例具体含义为下一个处理请求的对象
2.具体请求处理角色:请求处理的行为的具体实现者
4.优点
1.请求和处理分开实现两者之间的解耦,请求者不必知道究竟是哪个处理者处理了请求,请求处理者也不必知道请求中的具体细节。每个请求关注点不一样,导致请求处理者没有必要关注请求的全貌
5.缺点
1.性能问题,请求必须要从职责链的链头遍历到链尾。尤其是请求处理链特别长的情况下。可以在具体的请求处理者中添加return。让请求得到处理后返回。
2.调试不方便。链比较长的情况下调试可能会变的困难
6.使用场景
1.请求需要多个对象处理
2.判断逻辑过多时可以考虑该场景
7.code
抽象处理角色
public abstract class Duty {
protected Duty duty;
public void setDuty(Duty duty) {
this.duty = duty;
}
public abstract void raise(float salary);
}
具体处理角色
public class LeaderDuty extends Duty{
@Override
public void raise(float salary) {
if(salary < 500 ) {
System.out.println("职责范围内,Leader 同意加薪");
} else {
System.out.println("职责范围外需要找项目经理审批");
if(this.duty != null) {
duty.raise(salary);
}
}
}
}
public class PMDuty extends Duty {
@Override
public void raise(float salary) {
if(salary < 1000 ) {
System.out.println("职责范围内,PM 同意加薪");
} else {
System.out.println("职责范围外需要找总经理审批");
if(this.duty != null) {
duty.raise(salary);
}
}
}
}
public class ManagerDuty extends Duty {
@Override
public void raise(float salary) {
if(salary < 2000 ) {
System.out.println("职责范围内,总经理 同意加薪");
} else {
System.out.println("超出规定");
}
}
}
客户端
public class Client {
public static void main(String[] args){
Duty leader = new LeaderDuty();
Duty pm = new PMDuty();
Duty manager = new ManagerDuty();
leader.setDuty(pm);
pm.setDuty(manager);
leader.raise(600);
}
}
在采用该模式的时,需要控制职责链的长度,当链的长度超过某个阀值时,则不允许建立该链
可以在采用门面模式进行隔离,也即是说客户端只需要传递最初始的请求处理对对象即可
采用门面模式隔离
public class DutyFacade {
public LeaderDuty duty = null;
public DutyFacade(LeaderDuty duty) {
this.duty = duty;
}
public void raise(float raise) {
Duty pm = new PMDuty();
Duty manager = new ManagerDuty();
this.duty.setDuty(pm);
pm.setDuty(manager);
this.duty.raise(raise);
}
}
客户端
public class Client {
public static void main(String[] args){
DutyFacade dutyFacade = new DutyFacade(new LeaderDuty());
dutyFacade.raise(600);
}
}
采用门面模式进行隔离时,必须要确保请求的处理必须是从链头开始,所以需要门面模式约束客户端,也就是说门面模式初始化请求处理者不能够依赖以抽象需要依赖具体的请求处理者且该请求处理者处于链首