责任链设计模式,顾名思义就是通过一条链来处理某个请求,当请求满足某个节点的条件时就在这里被处理,否则的话就会继续向下执行
定义:
使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
使用场景:
多个对象可以处理同一个请求,但具体由哪个对象处理则在运行时动态决定。
在请求处理者不明确的情况下向多个对象中的一个提交一个请求。
需要动态指定一组对象处理请求。
简单例子:
/**
* 抽象的处理者
*/
public abstract class AbstractHandler {
public AbstractHandler nextHandler; // 下一节点上的处理者对象
public final void handleRequest(AbstractRequest request) {
if (getHandlerLevel() == request.getRequestLevel()) {
handle(request);
} else {
if (nextHandler != null) {
nextHandler.handleRequest(request);
} else {
Log.i("aaaa", "All of handler can not handle the request");
}
}
}
public abstract int getHandlerLevel();
public abstract void handle(AbstractRequest request);
}
public class Handler1 extends AbstractHandler {
@Override
public int getHandlerLevel() {
return 1;
}
@Override
public void handle(AbstractRequest request) {
Log.i("aaaaa", "Handler1 handle request:" + request.getRequestLevel());
}
}
public class Handler2 extends AbstractHandler {
@Override
public int getHandlerLevel() {
return 2;
}
@Override
public void handle(AbstractRequest request) {
Log.i("aaaaa", "Handler2 handle request:" + request.getRequestLevel());
}
}
public class Handler3 extends AbstractHandler {
@Override
public int getHandlerLevel() {
return 3;
}
@Override
public void handle(AbstractRequest request) {
Log.i("aaaaa", "Handler3 handle request:" + request.getRequestLevel());
}
}
/**
* 抽象的请求者
*/
public abstract class AbstractRequest {
private Object obj;
public AbstractRequest(Object obj) {
this.obj = obj;
}
public Object getContent() {
return obj;
}
public abstract int getRequestLevel();
}
public class Request1 extends AbstractRequest {
public Request1(Object obj) {
super(obj);
}
@Override
public int getRequestLevel() {
return 1;
}
}
public class Request2 extends AbstractRequest {
public Request2(Object obj) {
super(obj);
}
@Override
public int getRequestLevel() {
return 2;
}
}
public class Request3 extends AbstractRequest {
public Request3(Object obj) {
super(obj);
}
@Override
public int getRequestLevel() {
return 3;
}
}
// 实现类
public void handlerDesigner() {
AbstractHandler handler1 = new Handler1();
AbstractHandler handler2 = new Handler2();
AbstractHandler handler3 = new Handler3();
handler1.nextHandler = handler2;
handler2.nextHandler = handler3;
AbstractRequest request1 = new Request1("Request1");
AbstractRequest request2 = new Request2("Request2");
AbstractRequest request3 = new Request3("Request3");
handler3.handleRequest(request2);
handler2.handleRequest(request1);
handler1.handleRequest(request3);
}
上面的例子比较简单,其实就是将handler1的下一个节点设置成handler2,将handler2的下一个节点设置成handler3。这里我就不多累赘了,一看就懂
下面我们用一个更清楚易懂的例子来进行说明
在公司内部员工请假一般情况是这样的:员工在OA系统中提交一封请假邮件,该邮件会自动转发到你的直接上级领导邮箱里,如果你的请假的情况特殊的话,该邮件也会转发到你上级的上级的邮箱,根据请假的情况天数多少,系统会自动转发相应的责任人的邮箱。我们就以这样一种场景为例完成一个责任链模式的代码。为了更清晰的描述这种场景我们规定如下:
① GroupLeader(组长 ):他能批准的假期为2天,如果请假天数超过2天就将请假邮件自动转发到组长和经理邮箱。
② Manager(经理):他能批准的假期为4天以内,如果请假天数大于4天将该邮件转发到自动转发到组长、经理和部门领导的邮箱。
③ DepartmentHeader(部门领导):他能批准的假期为7天以内,如果大于7天就只批准7天。
/**
* 请求发起类,用于保存请求的一些信息
*/
public class Request {
private String name;
private String reason;
private int days;
private String groupLeaderInfo;
private String managerInfo;
private String departmentHeaderInfo;
private String customInfo;
private Request(Builder builder) {
super();
this.name = builder.name;
this.reason = builder.reason;
this.days = builder.days;
this.groupLeaderInfo = builder.groupLeaderInfo;
this.managerInfo = builder.managerInfo;
this.departmentHeaderInfo = builder.departmentHeaderInfo;
this.customInfo = builder.customInfo;
}
public static class Builder {
private String name;
private String reason;
private int days;
private String groupLeaderInfo;
private String managerInfo;
private String departmentHeaderInfo;
private String customInfo;
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setReason(String reason) {
this.reason = reason;
return this;
}
public Builder setDays(int days) {
this.days = days;
return this;
}
public Builder setGroupLeaderInfo(String groupLeaderInfo) {
this.groupLeaderInfo = groupLeaderInfo;
return this;
}
public Builder setManagerInfo(String managerInfo) {
this.managerInfo = managerInfo;
return this;
}
public Builder newBuilder(Request request) {
this.name = request.name;
this.days = request.days;
this.reason = request.reason;
if (request.groupLeaderInfo != null
&& !request.groupLeaderInfo.equals("")) {
this.groupLeaderInfo = request.groupLeaderInfo;
}
if (request.managerInfo != null && !request.managerInfo.equals("")) {
this.managerInfo = request.managerInfo;
}
if (request.departmentHeaderInfo != null
&& !request.departmentHeaderInfo.equals("")) {
this.departmentHeaderInfo = request.departmentHeaderInfo;
}
if (request.customInfo != null && !request.customInfo.equals("")) {
this.customInfo = request.customInfo;
}
return this;
}
public Request build() {
return new Request(this);
}
}
public String name() {
return name;
}
public int days() {
return days;
}
@Override
public String toString() {
return "Request [name=" + name + ", reason=" + reason + ", days="
+ days + ",customInfo=" + customInfo + ", groupLeaderInfo="
+ groupLeaderInfo + ", managerInfo=" + managerInfo
+ ", departmentHeaderInfo=" + departmentHeaderInfo + "]";
}
}
/**
* 请求处理类
*/
public class Result {
private boolean isRatify;
public String info;
Result(boolean isRatify, String info) {
super();
this.isRatify = isRatify;
this.info = info;
}
@Override
public String toString() {
return "Result [isRatify=" + isRatify + ", info=" + info + "]";
}
}
/**
* 关键类,用于将请求发送到下一个节点
*/
public class RealChain implements Ratify.Chain {
public Request request;
private List<Ratify> ratifyList;
private int index;
RealChain(Request request, List<Ratify> ratifyList, int index) {
this.request = request;
this.ratifyList = ratifyList;
this.index = index;
}
@Override
public Request request() {
return request;
}
@Override
public Result proceed(Request request) {
Result proceed = null;
if (ratifyList.size() > index) {
RealChain realChain = new RealChain(request, ratifyList, index + 1);
Ratify ratify = ratifyList.get(index);
proceed = ratify.deal(realChain);
}
return proceed;
}
}
public interface Ratify {
// 处理请求
public Result deal(Chain chain);
/**
* 接口描述:对request和Result封装,用来转发
*/
interface Chain {
// 获取当前request
Request request();
// 转发request
Result proceed(Request request);
}
}
public class GroupLeader implements Ratify {
@Override
public Result deal(Chain chain) {
Request request = chain.request();
System.out.println("GroupLeader=====>request:" + request.toString());
if (request.days() > 1) {
// 包装新的请求对象,然后传递给上一级,交给上级处理
Request newRequest = new Request.Builder().newBuilder(request).setGroupLeaderInfo(request.name() + "平时表现不错,而且现在项目也不忙").build();
return chain.proceed(newRequest);
}
return new Result(true, "GroupLeader:早去早回");
}
}
public class Manager implements Ratify {
@Override
public Result deal(Chain chain) {
Request request = chain.request();
System.out.println("Manager=====>request:" + request.toString());
if (request.days() > 3) {
// 构建新的Request
Request newRequest = new Request.Builder().newBuilder(request)
.setManagerInfo(request.name() + "每月的KPI考核还不错,可以批准")
.build();
return chain.proceed(newRequest);
}
return new Result(true, "Manager:早点把事情办完,项目离不开你");
}
}
public class DepartmentHeader implements Ratify {
@Override
public Result deal(Chain chain) {
Request request = chain.request();
System.out.println("DepartmentHeader=====>request:"
+ request.toString());
if (request.days() > 7) {
return new Result(false, "你这个完全没必要");
}
return new Result(true, "DepartmentHeader:不要着急,把事情处理完再回来!");
}
}
public class ChainOfResponsibilityClient {
private ArrayList<Ratify> ratifies;
ChainOfResponsibilityClient() {
ratifies = new ArrayList<>();
}
public void addRatify(Ratify ratify) {
ratifies.add(ratify);
}
public Result execute(Request request) {
ArrayList<Ratify> arrayList = new ArrayList<>();
arrayList.addAll(ratifies);
arrayList.add(new GroupLeader());
arrayList.add(new Manager());
arrayList.add(new DepartmentHeader());
RealChain realChain = new RealChain(request,arrayList,0);
return realChain.proceed(request);
}
}
/**
* 测试类
*/
public class Main {
public static void main(String[] args) {
Request request = new Request.Builder().setName("张三").setDays(5)
.setReason("事假").build();
ChainOfResponsibilityClient client = new ChainOfResponsibilityClient();
Result result = client.execute(request);
System.out.println("结果:" + result.toString());
}
}
如果你完全弄懂了上面的例子,恭喜你,责任链模式你已经基本掌握了。对于任何设计模式而言,我们更重要的是学习它里面的思想而不要拘泥于它的代码,因为代码是随意的,只有真正掌握到了思想的精髓,以后才能写出更加优雅的代码。