接下来再定义“批准结果”对象Result:
/** * 类描述:结果对象 * * @author lzy * */ public class Result { public boolean isRatify; public String info; public Result() { } public Result(boolean isRatify, String info) { super(); this.isRatify = isRatify; this.info = info; } public boolean isRatify() { return isRatify; } public void setRatify(boolean isRatify) { this.isRatify = isRatify; } public String getReason() { return info; } public void setReason(String info) { this.info = info; } @Override public String toString() { return "Result [isRatify=" + isRatify + ", info=" + info + "]"; } }
②我们接下来再来定义一个接口,这个接口用于处理Request和获取请求结果Result。
/** * 接口描述:处理请求 * * @author lzy * */ public interface Ratify { // 处理请求 public Result deal(Chain chain); /** * 接口描述:对request和Result封装,用来转发 */ interface Chain { // 获取当前request Request request(); // 转发request Result proceed(Request request); } }
看到上面的接口,可能会有人迷惑:在接口Ratify中为什么又定义一个Chain接口呢?其实这个接口是单独定义还是内部接口没有太大关系,但是考虑到Chain接口与Ratify接口的关系为提高内聚性就定义为内部接口了。定义Ratify接口是为了处理Request那为什么还要定义Chain接口呢?这正是责任链接口的精髓之处:转发功能及可动态扩展“责任人”,这个接口中定义了两个方法一个是request()就是为了获取request,如果当前Ratify的实现类获取到request之后发现自己不能处理或者说自己只能处理部分请求,那么他将自己的那部分能处理的就处理掉,然后重新构建一个或者直接转发Request给下一个责任人。可能这点说的不容易理解,我举个例子,在Android与后台交互中如果使用了Http协议,当然我们可能使用各种Http框架如HttpClient、OKHttp等,我们只需要发送要请求的参数就直接等待结果了,这个过程中你可能并没有构建请求头,那么框架帮你把这部分工作给做了,它做的工程中如果使用了责任链模式的话,它肯定会将Request进行包装(也就是添加请求头)成新的Request,我们姑且加他为Request1,如果你又希望Http做本地缓存,那么Request1又会被转发到并且重新进一步包装为Request2。总之Chain这个接口就是起到对Request进行重新包装的并将包装后的Request进行下一步转发的作用。如果还不是很明白也没关系,本实例会演示这一功能机制。 ③上面说Chain是用来对Request重新包装以及将包装后的Request进行下一步转发用的,那我们就具体实现一下: /** * 类描述:实现Chain的真正的包装Request和转发功能 * * @author lzy * */ public class RealChain implements Chain { public Request request; public List<Ratify> ratifyList; public int index; /** * 构造方法 * * @param ratifyList * Ratify接口的实现类集合 * @param request * 具体的请求Request实例 * @param index * 已经处理过该request的责任人数量 */ public RealChain(List<Ratify> ratifyList, Request request, int index) { this.ratifyList = ratifyList; this.request = request; this.index = index; } /** * 方法描述:具体转发功能 */ @Override public Result proceed(Request request) { Result proceed = null; if (ratifyList.size() > index) { RealChain realChain = new RealChain(ratifyList, request, index + 1); Ratify ratify = ratifyList.get(index); proceed = ratify.deal(realChain); } return proceed; } /** * 方法描述:返回当前Request对象或者返回当前进行包装后的Request对象 */ @Override public Request request() { return request; } }
④ 经过上面几步我们已经完成了责任链模式的核心功能,接下来我们定义几个相关责任对象:GroupLeader、Manager和DepartmentHeader,并让他们实现Ratify接口。
/** * 组长 * * @author lzy * */ 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对象 Request newRequest = new Request.Builder().newRequest(request) .setManagerInfo(request.name() + "平时表现不错,而且现在项目也不忙") .build(); return chain.proceed(newRequest); } return new Result(true, "GroupLeader:早去早回"); } } /** * 经理 * * @author lzy * */ 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().newRequest(request) .setManagerInfo(request.name() + "每月的KPI考核还不错,可以批准") .build(); return chain.proceed(newRequest); } return new Result(true, "Manager:早点把事情办完,项目离不开你"); } } /** * 部门领导 * * @author lzy * */ 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:不要着急,把事情处理完再回来!"); } }
到此,责任链模式的一个Demo就算是完成了,但为了方便调用,我们在写一个该责任链模式的客户端工具类ChainOfResponsibilityClient 如下:
/** * 类描述:责任链模模式工具类 * * @author lzy * */ public class ChainOfResponsibilityClient { private ArrayList<Ratify> ratifies; public ChainOfResponsibilityClient() { ratifies = new ArrayList<Ratify>(); } /** * 方法描述:为了展示“责任链模式”的真正的迷人之处(可扩展性),在这里构造该方法以便添加自定义的“责任人” * * @param ratify */ public void addRatifys(Ratify ratify) { ratifies.add(ratify); } /** * 方法描述:执行请求 * * @param request * @return */ public Result execute(Request request) { ArrayList<Ratify> arrayList = new ArrayList<Ratify>(); arrayList.addAll(ratifies); arrayList.add(new GroupLeader()); arrayList.add(new Manager()); arrayList.add(new DepartmentHeader()); RealChain realChain = new RealChain(this, arrayList, request, 0); return realChain.proceed(request); } }
OK,我们测试一下见证奇迹吧:
/** * 类描述:责任链模式测试类 * * @author lzy * */ 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()); } }
这个请求是张三请事假5天,按照我们的约定应该请求会到达部门领导手里,且他看到请求的样式为:“ [name=张三, reason=事假, days=5customInfo=null, groupLeaderInfo=张三平时表现不错,而且现在项目也不忙, managerInfo=张三每月的KPI考核还不错,可以批准, departmentHeaderInfo=null]” 我们看一下打印的日志: GroupLeader=====>request:Request [name=张三, reason=事假, days=5customInfo=null, groupLeaderInfo=null, managerInfo=null, departmentHeaderInfo=null] Manager=====>request:Request [name=张三, reason=事假, days=5customInfo=null, groupLeaderInfo=张三平时表现不错,而且现在项目也不忙, managerInfo=null, departmentHeaderInfo=null] DepartmentHeader=====>request:Request [name=张三, reason=事假, days=5customInfo=null, groupLeaderInfo=张三平时表现不错,而且现在项目也不忙, managerInfo=张三每月的KPI考核还不错,可以批准, departmentHeaderInfo=null] 结果:Result [isRatify=true, info=DepartmentHeader:不要着急,把事情处理完再回来!]
OK,和预期一样完美。刚开始就提到这个责任链模式是可以“动态扩展的”,我们验证一下,首先自定义一个“责任人”(其实也可以叫拦截器):
/** * 类描述:自定义“责任人” * * @author lzy * */ public class CustomInterceptor implements Ratify { @Override public Result deal(Chain chain) { Request request = chain.request(); System.out.println("CustomInterceptor=>" + request.toString()); String reason = request.reason(); if (reason != null && reason.equals("事假")) { Request newRequest = new Request.Builder().newRequest(request) .setCustomInfo(request.name() + "请的是事假,而且很着急,请领导重视一下") .build(); System.out.println("CustomInterceptor=>转发请求"); return chain.proceed(newRequest); } return new Result(true, "同意请假"); } }
然后在测试类Main.java中调用如下:
/** * 类描述:责任链模式测试类 * * @author lzy * */ public class Main { public static void main(String[] args) { Request request = new Request.Builder().setName("张三").setDays(5) .setReason("事假").build(); ChainOfResponsibilityClient client = new ChainOfResponsibilityClient(); client.addRatifys(new CustomInterceptor()); Result result = client.execute(request); System.out.println("结果:" + result.toString()); } }
OK,看一下日志:
哈哈,责任链模式功能之强大还要多用多体会呀!