4-责任链(常用)
责任链(Chain Of Responsibility)
Intent
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链发送该请求,直到有一个对象处理它为止。
Class Diagram
Handler:定义处理请求的接口,并且实现后继链(successor)
Implementation
public abstract class Handler {
protected Handler successor;
public Handler(Handler successor) {
this.successor = successor;
}
protected abstract void handleRequest(Request request);
}
public class ConcreteHandler1 extends Handler {
public ConcreteHandler1(Handler successor) {
super(successor);
}
@Override
protected void handleRequest(Request request) {
if (request.getType() == RequestType.TYPE1) {
System.out.println(request.getName() + " is handle by ConcreteHandler1");
return;
}
if (successor != null) {
successor.handleRequest(request);
}
}
}
public class ConcreteHandler2 extends Handler {
public ConcreteHandler2(Handler successor) {
super(successor);
}
@Override
protected void handleRequest(Request request) {
if (request.getType() == RequestType.TYPE2) {
System.out.println(request.getName() + " is handle by ConcreteHandler2");
return;
}
if (successor != null) {
successor.handleRequest(request);
}
}
}
public class Request {
private RequestType type;
private String name;
public Request(RequestType type, String name) {
this.type = type;
this.name = name;
}
public RequestType getType() {
return type;
}
public String getName() {
return name;
}
}
public enum RequestType {
TYPE1, TYPE2
}
public class Client {
public static void main(String[] args) {
Handler handler1 = new ConcreteHandler1(null);
Handler handler2 = new ConcreteHandler2(handler1);
Request request1 = new Request(RequestType.TYPE1, "request1");
handler2.handleRequest(request1);
Request request2 = new Request(RequestType.TYPE2, "request2");
handler2.handleRequest(request2);
}
}
Business Scenario
模拟上线审批
模拟在618期间系统上线的审批流程,随着时间的邻近,上线的审批流程会越来越复杂
模拟审核服务
/**
* 模拟审核服务
* 1. auth 审核流程
* 2. queryAuthInfo 查询审核信息(时间)
*/
public class AuthService {
private static Map<String, Date> authMap = new ConcurrentHashMap<String, Date>();
public static Date queryAuthInfo(String uId, String orderId) {
return authMap.get(uId.concat(orderId));
}
public static void auth(String uId, String orderId) {
authMap.put(uId.concat(orderId), new Date());
}
}
责任链模式实现
审核返回的结果
public class AuthInfo {
private String code;
private String info = "";
public AuthInfo(String code, String ...infos) {
this.code = code;
for (String str:infos){
this.info = this.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;
}
}
责任链抽象
/**
* 审核规定;
* 1. 601-610 三级审批 + 二级审批
* 2. 611-620 三级审批 + 二级审批 + 一级审批
* 3. 其他时间 三级审批
*/
public abstract class AuthLink {
protected Logger logger = LoggerFactory.getLogger(AuthLink.class);
protected SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 时间格式化
protected String levelUserId; // 级别人员ID
protected String levelUserName; // 级别人员姓名
private AuthLink next; // 责任链
public AuthLink(String levelUserId, String levelUserName) {
this.levelUserId = levelUserId;
this.levelUserName = levelUserName;
}
public AuthLink next() {
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 {
public Level1AuthLink(String levelUserId, String levelUserName) {
super(levelUserId, levelUserName);
}
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.next();
if (null == next) {
return new AuthInfo("0000", "单号:", orderId, " 状态:一级审批完成负责人", " 时间:", f.format(date), " 审批人:", levelUserName);
}
return next.doAuth(uId, orderId, authDate);
}
}
/**
* 二级负责人
*/
public class Level2AuthLink extends AuthLink {
private Date beginDate = f.parse("2022-06-11 00:00:00");
private Date endDate = f.parse("2022-06-20 23:59:59");
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.next();
if (null == next) {
return new AuthInfo("0000", "单号:", orderId, " 状态:二级审批完成负责人", " 时间:", f.format(date), " 审批人:", levelUserName);
}
if (authDate.before(beginDate) || authDate.after(endDate)) {
return new AuthInfo("0000", "单号:", orderId, " 状态:二级审批完成负责人", " 时间:", f.format(date), " 审批人:", levelUserName);
}
logger.info("code = {} 单号:{} 状态:二级审批完成负责人 时间:{} 审批人:{}", "0000", orderId, f.format(date), levelUserName);
return next.doAuth(uId, orderId, authDate);
}
}
/**
* 三级负责人
*/
public class Level3AuthLink extends AuthLink {
private Date beginDate = f.parse("2022-06-01 00:00:00");
private Date endDate = f.parse("2022-06-25 23:59:59");
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.next();
if (null == next) {
return new AuthInfo("0000", "单号:", orderId, " 状态:三级审批负责人完成", " 时间:", f.format(date), " 审批人:", levelUserName);
}
if (authDate.before(beginDate) || authDate.after(endDate)) {
return new AuthInfo("0000", "单号:", orderId, " 状态:三级审批负责人完成", " 时间:", f.format(date), " 审批人:", levelUserName);
}
logger.info("code = {} 单号:{} 状态:三级审批完成负责人 时间:{} 审批人:{}", "0000", orderId, f.format(date), levelUserName);
return next.doAuth(uId, orderId, authDate);
}
}
测试
public class ApiTest {
private Logger logger = LoggerFactory.getLogger(ApiTest.class);
@Test
public void test_AuthLink() throws ParseException {
AuthLink authLink = new Level3AuthLink("1000013", "小霞")
.appendNext(new Level2AuthLink("1000012", "小刚")
.appendNext(new Level1AuthLink("1000011", "小智")));
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
// 模拟三级负责⼈人审批
AuthService.auth("1000013", "1000998004813441");
logger.info("测试结果:{}", "模拟三级负责⼈人审批");
logger.info("测试结果:{}", JSON.toJSONString(authLink.doAuth("⼩小z",
"1000998004813441", new Date())));
logger.info("===============");
// 模拟⼆二级负责⼈人审批
AuthService.auth("1000012", "1000998004813441");
logger.info("测试结果:{}", "模拟三、二级负责⼈人审批");
logger.info("测试结果:{}", JSON.toJSONString(authLink.doAuth("⼩小z",
"1000998004813441", format.parse("2022-06-01"))));
logger.info("===============");
// 模拟⼀一级负责⼈人审批
AuthService.auth("1000011", "1000998004813441");
logger.info("测试结果:{}", "模拟三、二、一级负责⼈人审批");
logger.info("测试结果:{}", JSON.toJSONString(authLink.doAuth("小z",
"1000998004813441", format.parse("2022-06-11"))));
}
}
Summary
责任链模式通过一条链关联了所有的处理过程,当来请求后,可以只是链路上的某个处理类处理,也可以是链路上的多个处理类处理,这样让逻辑更加的明确,也有了处理的先后顺序,如果在结合工厂模式,还方便拓展。
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 TechTrekker
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果