1 职责链模式介绍
2 职责链模式原理
3 职责链模式实现
责任链模式的实现非常简单,每一个具体的处理类都会保存在它之后的下一个处理类。当处理完成后,就会调用设置好的下一个处理类,直到最后一个处理类不再设置下一个处理类,这时处理链条全部完成。
public class RequestData{
private String data;
public RequestData(String data) {
this.data = data;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
/**
* 抽象的处理者类
**/
public abstract class Handler {
//后继处理者的引用
protected Handler successor;
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public abstract void handle(RequestData requestData);
}
public class HandlerA extends Handler {
@Override
public void handle(RequestData requestData) {
System.out.println("HandlerA 执行代码逻辑! 处理: " + requestData.getData());
requestData.setData(requestData.getData().replace("A",""));
//判断时候继续向后调用处理器
if(successor != null){
successor.handle(requestData);
}else{
System.out.println("执行中止");
}
}
}
public class HandlerB extends Handler {
@Override
public void handle(RequestData requestData) {
System.out.println("HandlerB 执行代码逻辑! 处理: " + requestData.getData());
requestData.setData(requestData.getData().replace("B",""));
//判断时候继续向后调用处理器
if(successor != null){
successor.handle(requestData);
}else{
System.out.println("执行中止");
}
}
}
public class HandlerC extends Handler {
@Override
public void handle(RequestData requestData) {
System.out.println("HandlerC 执行代码逻辑! 处理: " + requestData.getData());
requestData.setData(requestData.getData().replace("C",""));
//判断时候继续向后调用处理器
if(successor != null){
successor.handle(requestData);
}else{
System.out.println("执行中止");
}
}
}
public class Client {
public static void main(String[] args) {
Handler h1 = new HandlerA();
Handler h2 = new HandlerB();
Handler h3 = new HandlerC();
//创建处理链
h1.setSuccessor(h2);
h2.setSuccessor(h3);
RequestData requestData = new RequestData("请求数据: ABCD");
//调用处理链头部的方法
h1.handle(requestData);
}
}
4 职责链模式应用实例
1) 不使用设计模式
/**
* 封装审核信息
**/
public class AuthInfo {
private String code; //状态码
private String info = ""; //审核相关信息
public AuthInfo(String code, String... infos) {
this.code = code;
for (String str : infos) {
this.info = info.concat(str+ " ");
}
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
@Override
public String toString() {
return "AuthInfo{" +
"code='" + code + '\'' +
", info='" + info + '\'' +
'}';
}
}
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* 模拟审核服务
**/
public class AuthService {
//审核信息容器 key:审批人Id+审批单Id , value:审批时间
private static Map<String, Date> authMap = new HashMap<>();
/**
* 审核方法
* @param uId 审核人id
* @param orderId 审核单id
*/
public static void auth(String uId , String orderId){
System.out.println("进入审批流程,审批人ID: " + uId);
authMap.put(uId.concat(orderId),new Date());
}
/**
* 查询审核结果
* @param uId
* @param orderId
* @return: java.util.Date
*/
public static Date queryAuthInfo(String uId , String orderId){
return authMap.get(uId.concat(orderId));
}
}
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 审核申请接口
**/
public class AuthController {
/**
* 审核方法
* @param name 申请人姓名
* @param orderId 申请单ID
* @param authDate 申请时间
* @return: AuthInfo
*/
public AuthInfo doAuth(String name, String orderId, Date authDate) throws ParseException {
//三级审批
Date date = null;
//查询是否存在审核信息,虚拟三级审核人ID: 1000013
date = AuthService.queryAuthInfo("1000013", orderId);
if(date == null){
return new AuthInfo("0001","单号: " + orderId ,
"状态: 等待三级审批负责人进行审批");
}
/**
* 二级审批
* 查询是否存在审核信息,虚拟二级审核人ID: 1000012
* 二级审核人审核申请单的时间范围为: 11-01 ~ 11-10
*/
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
if(authDate.after(sdf.parse("2022-10-31 00:00:00")) && authDate.before(sdf.parse("2022-11-11 00:00:00")) ){
//条件成立,查询二级审核信息
date = AuthService.queryAuthInfo("1000012",orderId);
if(date == null){
return new AuthInfo("0001","单号: " + orderId ,
"状态: 等待二级审批负责人进行审批");
}
}
/**
* 一级审批
* 查询是否存在审核信息,虚拟二级审核人ID: 1000012
* 二级审核人审核申请单的时间范围为: 11-11 ~ 11-31
*/
if(authDate.after(sdf.parse("2022-11-10 00:00:00")) && authDate.before(sdf.parse("2022-11-31 00:00:00")) ){
//条件成立,查询二级审核信息
date = AuthService.queryAuthInfo("1000011",orderId);
if(date == null){
return new AuthInfo("0001","单号: " + orderId ,
"状态: 等待一级审批负责人进行审批");
}
}
return new AuthInfo("0001","单号: " + orderId ,"申请人: " + name," 状态:审批完成!");
}
}
public class Client {
public static void main(String[] args) throws ParseException {
AuthController controller = new AuthController();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = sdf.parse("2022-11-06 00:00:00");
//模拟审核请求及审批操作
AuthInfo info1 = controller.doAuth("研发小周", "100001000010000", date);
System.out.println("当前审核状态: " + info1.getInfo());
AuthService.auth("1000013","100001000010000");
System.out.println("三级审批负责人审批完成,审批人: 王工");
System.out.println("=================================================");
AuthInfo info2 = controller.doAuth("研发小周", "100001000010000", date);
System.out.println("当前审核状态: " + info2.getInfo());
AuthService.auth("1000012","100001000010000");
System.out.println("二级审批负责人审批完成,审批人: 周经理");
System.out.println("=================================================");
AuthInfo info3 = controller.doAuth("研发小周", "100001000010000", date);
System.out.println("当前审核状态: " + info3.getInfo());
AuthService.auth("1000012","100001000010000");
System.out.println("一级审批负责人审批完成,审批人: 罗总");
}
}
2 ) 职责链模式重构代码
下图是为当前业务设计的责任链结构,统一抽象类AuthLink 下 有三个子类,将三
个子类的执行通过编排,模拟出一条链路,这个链路就是业务中的责任链.
/**
* 抽象审核链类
**/
public abstract class AuthLink {
protected Logger logger = (Logger) LoggerFactory.getLogger(AuthLink.class);
protected SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
protected String levelUserId; //审核人id
protected String levelUserName; //审核人姓名
protected AuthLink next; //表示持有下一个处理对象的引用
public AuthLink(String levelUserId, String levelUserName) {
this.levelUserId = levelUserId;
this.levelUserName = levelUserName;
}
//获取下一个处理器
public AuthLink getNext() {
return next;
}
//向责任链中添加处理器
public AuthLink appendNext(AuthLink next){
this.next = next;
return this;
}
//抽象审核方法
public abstract AuthInfo doAuth(String uId, String orderId, Date authDate);
}
public class Level1AuthLink extends AuthLink {
private Date beginDate = sdf.parse("2022-11-11 00:00:00");
private Date endDate = sdf.parse("2022-11-31 00:00:00");
public Level1AuthLink(String levelUserId, String levelUserName) throws ParseException {
super(levelUserId, levelUserName);
}
@Override
public AuthInfo doAuth(String uId, String orderId, Date authDate) {
Date date = AuthService.queryAuthInfo(levelUserId, orderId);
if(null == date){
return new AuthInfo("0001","单号: "+
orderId," 状态: 待一级审核人审批", levelUserName);
}
AuthLink next = super.getNext();
if(next == null){
return new AuthInfo("0001","单号: "+
orderId," 状态: 一级审批完成", "审批人: " + levelUserName);
}
if(authDate.before(beginDate) || authDate.after(endDate)){
return new AuthInfo("0001","单号: "+
orderId," 状态: 一级审批完成", "审批人: " + levelUserName);
}
return next.doAuth(uId,orderId,authDate);
}
}
public class Level2AuthLink extends AuthLink {
private Date beginDate = sdf.parse("2022-11-11 00:00:00");
private Date endDate = sdf.parse("2022-11-31 00:00:00");
public Level2AuthLink(String levelUserId, String levelUserName) throws ParseException {
super(levelUserId, levelUserName);
}
@Override
public AuthInfo doAuth(String uId, String orderId, Date authDate) {
Date date = AuthService.queryAuthInfo(levelUserId, orderId);
if(null == date){
return new AuthInfo("0001","单号: "+
orderId," 状态: 待二级审核人审批", levelUserName);
}
AuthLink next = super.getNext();
if(next == null){
return new AuthInfo("0000","单号: "+
orderId," 状态: 二级审批完成", "审批人: " + levelUserName);
}
if(authDate.before(beginDate) || authDate.after(endDate)){
return new AuthInfo("0000","单号: "+
orderId," 状态: 二级审批完成", "审批人: " + levelUserName);
}
return next.doAuth(uId,orderId,authDate);
}
}
public class Level3AuthLink extends AuthLink {
public Level3AuthLink(String levelUserId, String levelUserName) throws ParseException {
super(levelUserId, levelUserName);
}
@Override
public AuthInfo doAuth(String uId, String orderId, Date authDate) {
Date date = AuthService.queryAuthInfo(levelUserId, orderId);
if(null == date){
return new AuthInfo("0001","单号: "+
orderId," 状态: 待三级审核人审批", levelUserName);
}
AuthLink next = super.getNext();
if(next == null){
return new AuthInfo("0000","单号: "+
orderId," 状态: 三级审批完成", "审批人: " + levelUserName);
}
return next.doAuth(uId,orderId,authDate);
}
}
public class Client {
private Logger logger = LoggerFactory.getLogger(Client.class);
@Test
public void test_Auth() throws ParseException {
//定义责任链
AuthLink authLink = new Level3AuthLink("1000013", "李工")
.appendNext(new Level2AuthLink("1000012", "王经理")
.appendNext(new Level1AuthLink("1000011", "罗总")));
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date currentDate = f.parse("2022-11-18 23:49:46");
logger.info("测试结果:{}", JSON.toJSONString(authLink.doAuth("研发牛马", "1000998004813441", currentDate)));
// // 模拟三级负责人审批
AuthService.auth("1000013", "1000998004813441");
logger.info("测试结果:{}", "模拟三级负责人审批,王工");
logger.info("测试结果:{}", JSON.toJSONString(authLink.doAuth("研发牛马", "1000998004813441", currentDate)));
// // 模拟二级负责人审批
AuthService.auth("1000012", "1000998004813441");
logger.info("测试结果:{}", "模拟二级负责人审批,张经理");
logger.info("测试结果:{}", JSON.toJSONString(authLink.doAuth("研发牛马", "1000998004813441", currentDate)));
// // 模拟一级负责人审批
AuthService.auth("1000011", "1000998004813441");
logger.info("测试结果:{}", "模拟一级负责人审批,段总");
logger.info("测试结果:{}", JSON.toJSONString(authLink.doAuth("研发牛马", "1000998004813441", currentDate)));
}
}
5 职责链模式总结