目录
1.责任链模式
定义:
适用的场景:
优点:
缺点:
责任链模式相关设计模式:
责任链模式的通用类图:
关键点是Handler这个抽象类中需要包含一个自己类型的对象,和一个设置下一个请求处理者的方法。
业务场景:我们公司请假需要提交申请,然后由组长审批同意,然后再由经理审批同意,ok这样才算是请假同意,当然请假需要说明缘由,谁请假,请多久等等信息。
2.类图:
package com.wx.design_pattern.chainresponsibility;
/**
* User: Mr.Wang
* Date: 2020/1/28
*/
public abstract class ApprovalHandler {
protected ApprovalHandler approvalHandler;
/**
* 设置下一个处理者是谁
*/
public void setNext(ApprovalHandler next) {
this.approvalHandler = next;
}
/**
* 审批的方法
*/
public abstract void approvalRequest(HolidayApplication holidayApplication);
}
几个处理者的子类:
package com.wx.design_pattern.chainresponsibility;
import org.springframework.util.StringUtils;
import java.util.Objects;
/**
* User: Mr.Wang
* Date: 2020/1/28
*/
public class GroupLeaderApprovalHandler extends ApprovalHandler {
@Override
public void approvalRequest(HolidayApplication holidayApplication) {
//组长检查请假人的姓名不为空
if (!StringUtils.isEmpty(holidayApplication.getApplierName())) {
System.out.println("请假者为:" + holidayApplication.getApplierName() + ",组长审批通过");
//如果调用链还没结束则继续。
if (!Objects.isNull(approvalHandler)) {
approvalHandler.approvalRequest(holidayApplication);
}
} else {
System.out.println("请假驳回,请假者不能为空");
return;
}
}
}
package com.wx.design_pattern.chainresponsibility;
import org.springframework.util.StringUtils;
import java.util.Objects;
/**
* User: Mr.Wang
* Date: 2020/1/28
*/
public class ManagerApprovalHandler extends ApprovalHandler {
@Override
public void approvalRequest(HolidayApplication holidayApplication) {
//经理审批请假的原因
if (!StringUtils.isEmpty(holidayApplication.getReason())) {
System.out.println("请假的原因为:" + holidayApplication.getReason() + ",经理审批通过");
if (!Objects.isNull(approvalHandler)) {
approvalHandler.approvalRequest(holidayApplication);
}
} else {
System.out.println("请假驳回,原因不能为空");
return;
}
}
}
假期类:
package com.wx.design_pattern.chainresponsibility;
import java.util.Date;
/**
* User: Mr.Wang
* Date: 2020/1/28
*/
public class HolidayApplication {
private String reason;
private String applierName;
private Date startTime;
private Date endTime;
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
public String getApplierName() {
return applierName;
}
public void setApplierName(String applierName) {
this.applierName = applierName;
}
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
}
测试:
package com.wx.design_pattern.chainresponsibility;
import java.util.Date;
/**
* User: Mr.Wang
* Date: 2020/1/28
*/
public class Test1 {
public static void main(String[] args) {
ManagerApprovalHandler managerApprovalHandler = new ManagerApprovalHandler();
GroupLeaderApprovalHandler groupLeaderApprovalHandler = new GroupLeaderApprovalHandler();
groupLeaderApprovalHandler.setNext(managerApprovalHandler);
HolidayApplication holidayApplication = new HolidayApplication();
holidayApplication.setApplierName("Mr.Wang");
holidayApplication.setReason("回家耍");
holidayApplication.setStartTime(new Date());
holidayApplication.setEndTime(new Date());
groupLeaderApprovalHandler.approvalRequest(holidayApplication);
}
}
效果:
改进 ,现在我把这个链式关系也做封装
要把这个链式的调用关系封装起来就要用到递归调用,而且是两个类之间的递归。
抽象的处理类:
package com.wx.design_pattern.chainresponsibility;
/**
* User: Mr.Wang
* Date: 2020/1/28
*/
public abstract class AbstractApprovalHandler {
public void process(Chain chain,HolidayApplication holidayApplication) {
approvalRequest(holidayApplication);
chain.execute(holidayApplication);
}
/**
* 审批的方法
*/
public abstract void approvalRequest(HolidayApplication holidayApplication);
}
封装的调用链类:
package com.wx.design_pattern.chainresponsibility;
import java.util.List;
/**
* User: Mr.Wang
* Date: 2020/1/28
*/
public class Chain {
private List<AbstractApprovalHandler> abstractApprovalHandlers;
private int index = 0;
public Chain(List<AbstractApprovalHandler> abstractApprovalHandlers) {
this.abstractApprovalHandlers = abstractApprovalHandlers;
}
//根据下表链式执行
public void execute(HolidayApplication holidayApplication) {
if (index >= abstractApprovalHandlers.size()) {
return;
}
abstractApprovalHandlers.get(index++).process(this, holidayApplication);
}
}
处理子类:
package com.wx.design_pattern.chainresponsibility;
import org.springframework.util.StringUtils;
import java.util.Objects;
/**
* User: Mr.Wang
* Date: 2020/1/28
*/
public class ManagerApprovalHandler extends AbstractApprovalHandler{
@Override
public void approvalRequest(HolidayApplication holidayApplication) {
//经理审批请假的原因
if (!StringUtils.isEmpty(holidayApplication.getReason())) {
System.out.println("请假的原因为:" + holidayApplication.getReason() + ",经理审批通过");
} else {
System.out.println("请假驳回,原因不能为空");
return;
}
}
}
package com.wx.design_pattern.chainresponsibility;
import org.springframework.util.StringUtils;
import java.util.Objects;
/**
* User: Mr.Wang
* Date: 2020/1/28
*/
public class GroupLeaderApprovalHandler extends AbstractApprovalHandler {
@Override
public void approvalRequest(HolidayApplication holidayApplication) {
//组长检查请假人的姓名不为空
if (!StringUtils.isEmpty(holidayApplication.getApplierName())) {
System.out.println("请假者为:" + holidayApplication.getApplierName() + ",组长审批通过");
// //如果调用链还没结束则继续。
// if (!Objects.isNull(approvalHandler)) {
// approvalHandler.approvalRequest(holidayApplication);
// }
} else {
System.out.println("请假驳回,请假者不能为空");
return;
}
}
}
测试:
//把链式调用的关系进行封装
Chain chain = new Chain(Arrays.asList(
new ManagerApprovalHandler(),
new GroupLeaderApprovalHandler()
));
HolidayApplication holidayApplication = new HolidayApplication();
holidayApplication.setApplierName("Mr.Wang");
holidayApplication.setReason("回家耍");
holidayApplication.setStartTime(new Date());
holidayApplication.setEndTime(new Date());
chain.execute(holidayApplication);
效果:
抽象的处理者实现三个职责:一是定义一个请求的处理方法
handleMessage
,唯一对外开 放的方法;二是定义一个链的编排方法setNext
,设置下一个处理者;三是定义了具体的请求 者必须实现的两个方法:定义自己能够处理的级别getHandlerLevel
和具体的处理任务
echo
。 责任链模式屏蔽了请求的处理过程,你发起一个请求到底是谁处理的,这个你不用关 心,只要你把请求抛给责任链的第一个处理者,最终会返回一个处理结果(当然也可以不做 任何处理),作为请求者可以不用知道到底是需要谁来处理的,这是责任链模式的核心,