1、责任链模式的定义:
责任链模式(Iterator Pattern)是一种行为型设计模式,使多个对象都有机会处理同一个请求,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
2、责任链模式的角色:
抽象处理器AbstractHandler:是一个接口或抽象类,定义要处理的方法。
具体处理器Handler:对抽象处理器的具体实现,重写处理方法,调用处理器链的方法。
处理器链HandlerChain:通过数组或链表组织各个具体的处理器形成一个处理器链,提供添加处理器的方法,并调用处理器的处理方法。
3、责任链模式的使用场景
1.多个对象可以处理同一个请求,但具体由哪个对象处理则在运行时动态决定。
2.在请求处理器个数未知的情况下,或者请求处理器可动态配置的情况下,可以使用责任链模式。
4、使用责任链模式的样例代码一
需求:当用户发起请求时,通过多个过滤器对请求数据进行过滤
抽象处理器:
package com.design.mode.responsibilityChain.responsibility01;
/**
* @Author: 倚天照海
* @Description: 抽象处理器
*/
public interface MyFilter {
boolean doFilter(MyRequest request, MyResponse response, MyFilterChain chain);
}
具体处理器:
package com.design.mode.responsibilityChain.responsibility01;
/**
* @Author: 倚天照海
* @Description: 一个具体处理器,登录过滤器
*/
public class LoginFilter implements MyFilter {
@Override
public boolean doFilter(MyRequest request, MyResponse response, MyFilterChain chain) {
String reqMsg = request.getReqMsg();
if (!reqMsg.contains("username") || !reqMsg.contains("password")){
System.out.println("登录失败,请重新登录");
return false;
}
//chain.doFilter(request,response,chain);
String resMsg = response.getResMsg();
resMsg += "--登录过滤器返回响应消息";
response.setResMsg(resMsg);
return true;
}
}
package com.design.mode.responsibilityChain.responsibility01;
/**
* @Author: 倚天照海
* @Description: 一个具体处理器,业务过滤器
*/
public class BusinessFilter implements MyFilter {
@Override
public boolean doFilter(MyRequest request, MyResponse response, MyFilterChain chain) {
String reqMsg = request.getReqMsg();
if (!reqMsg.contains("/filter")){
System.out.println("请求的接口路径不存在");
return false;
}
//chain.doFilter(request,response,chain);
String resMsg = response.getResMsg();
resMsg += "--业务逻辑处理完返回响应消息";
response.setResMsg(resMsg);
return true;
}
}
处理器链:
package com.design.mode.responsibilityChain.responsibility01;
import java.util.ArrayList;
import java.util.List;
/**
* @Author: 倚天照海
* @Description: 责任链模式,模拟javax.servlet.Filter和FilterChain
*/
public class MyFilterChain {
//private int index = 0;
private List<MyFilter> filterList = new ArrayList<MyFilter>();
/**
* 将处理器添加到处理器链中
*/
public MyFilterChain addFilter(MyFilter filter){
filterList.add(filter);
return this;
}
/**
* 使用这种方式判断,第三个参数chain可以不要了
*/
public void doFilter(MyRequest request, MyResponse response, MyFilterChain chain){
for (MyFilter filter : filterList){
//第三个参数chain可以不要了
if (!filter.doFilter(request, response, chain)){
break;
}
}
}
/*public void doFilter(MyRequest request, MyResponse response, MyFilterChain chain){
if (index == filterList.size()){
return;
}
MyFilter filter = filterList.get(index);
index++;
//调用处理器的方法
filter.doFilter(request, response, chain);
}*/
}
其中用到的实体类:
package com.design.mode.responsibilityChain.responsibility01;
/**
* @Author: 倚天照海
* @Description:
*/
public class MyRequest {
private String reqMsg;
public String getReqMsg() {
return reqMsg;
}
public void setReqMsg(String reqMsg) {
this.reqMsg = reqMsg;
}
}
package com.design.mode.responsibilityChain.responsibility01;
/**
* @Author: 倚天照海
* @Description:
*/
public class MyResponse {
private String resMsg;
public String getResMsg() {
return resMsg;
}
public void setResMsg(String resMsg) {
this.resMsg = resMsg;
}
}
测试类:
package com.design.mode.responsibilityChain.responsibility01;
/**
* @Author: 倚天照海
*/
public class RespChainTest01 {
public static void main(String[] args) {
String reqMsg = "{username:andy,password:123456,url:\"http://ip:port/filter\"}";
MyRequest request = new MyRequest();
request.setReqMsg(reqMsg);
MyResponse response = new MyResponse();
//创建具体的处理器和处理器链
MyFilterChain chain = new MyFilterChain();
MyFilter loginFilter = new LoginFilter();
MyFilter businessFilter = new BusinessFilter();
//将处理器添加到处理器链中
chain.addFilter(loginFilter).addFilter(businessFilter);
chain.doFilter(request,response,chain);
String resMsg = response.getResMsg();
System.out.println("得到响应结果=======" + resMsg);
}
}
5、使用责任链模式的样例代码二
需求:根据员工请假天数不同,组长、主管、经理分别审批
实体类:
package com.design.mode.responsibilityChain.responsibility02;
/**
* @Author: 倚天照海
* @Description: 请假请求实体类
*/
public class LeaveRequest {
private Integer days;
private String reason;
public LeaveRequest() {
}
public Integer getDays() {
return days;
}
public void setDays(Integer days) {
this.days = days;
}
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
@Override
public String toString() {
return "Leave{" +
"days=" + days +
", reason='" + reason + '\'' +
'}';
}
}
package com.design.mode.responsibilityChain.responsibility02;
/**
* @Author: 倚天照海
* @Description: 请假结果实体类
*/
public class Result {
/**
* 是否批准
*/
private boolean isRatify;
private String info;
public boolean isRatify() {
return isRatify;
}
public void setRatify(boolean ratify) {
isRatify = ratify;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
@Override
public String toString() {
return "Result{" +
"isRatify=" + isRatify +
", info='" + info + '\'' +
'}';
}
}
抽象处理器:
package com.design.mode.responsibilityChain.responsibility02;
/**
* @Author: 倚天照海
* @Description: 批准接口,抽象处理器
*/
public interface Ratify {
Result handle(LeaveRequest request, Result result, MyChain chain);
}
三个具体处理器:
package com.design.mode.responsibilityChain.responsibility02;
/**
* @Author: 倚天照海
* @Description: 一个具体处理器,组长实体类,只能批准两天内的假期
*/
public class GroupLeader implements Ratify {
@Override
public Result handle(LeaveRequest request, Result result, MyChain chain) {
Integer days = request.getDays();
if (days <= 2){
result.setRatify(true);
result.setInfo("组长同意,早去早回。");
} else {
//result.setRatify(true);
chain.doFilter(request,result,chain);
}
return result;
}
}
package com.design.mode.responsibilityChain.responsibility02;
/**
* @Author: 倚天照海
* @Description: 一个具体处理器,部门主管,可以批准4天内的假期
*/
public class DepartmentHead implements Ratify {
@Override
public Result handle(LeaveRequest request, Result result, MyChain chain) {
Integer days = request.getDays();
if (days <= 4){
result.setRatify(true);
result.setInfo("主管同意,路上注意安全。");
} else {
//result.setRatify(true);
chain.doFilter(request,result,chain);
}
return result;
}
}
package com.design.mode.responsibilityChain.responsibility02;
/**
* @Author: 倚天照海
* @Description: 一个具体处理器,部门经理,可以批准7天内的假期,超过7天不批准
*/
public class DepartmentManager implements Ratify {
@Override
public Result handle(LeaveRequest request, Result result, MyChain chain) {
Integer days = request.getDays();
if (days <= 7){
result.setRatify(true);
result.setInfo("经理同意,回去安心办事。");
} else {
result.setRatify(false);
result.setInfo("经理不同意,时间太久。");
chain.doFilter(request,result,chain);
}
return result;
}
}
处理器链:
package com.design.mode.responsibilityChain.responsibility02;
import java.util.ArrayList;
import java.util.List;
/**
* @Author: 倚天照海
* @Description: 处理器链,责任链模式
*/
public class MyChain {
private int index = 0;
private List<Ratify> filterList = new ArrayList<Ratify>();
public MyChain addFilter(Ratify ratify){
filterList.add(ratify);
return this;
}
public void doFilter(LeaveRequest request, Result result, MyChain chain){
if (index == filterList.size()){
return;
}
Ratify ratify = filterList.get(index);
index++;
ratify.handle(request, result, chain);
}
}
测试类:
package com.design.mode.responsibilityChain.responsibility02;
/**
* @Author: 倚天照海
* @Description:
*/
public class RespChainTest02 {
public static void main(String[] args) {
LeaveRequest request = new LeaveRequest();
request.setDays(3);
Result result = new Result();
MyChain chain = new MyChain();
Ratify leader = new GroupLeader();
Ratify head = new DepartmentHead();
Ratify manager = new DepartmentManager();
chain.addFilter(leader).addFilter(head).addFilter(manager);
chain.doFilter(request,result,chain);
System.out.println("请假结果======" + result);
}
}