1. 意图(Intent)
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链发送该请求,直到有一个对象处理它为止。
责任链通常需要先建立一个单向链表,然后调用方只需要调用头部节点就可以了,后面会自动流转下去。
比如流程审批就是一个很好的例子,只要终端用户提交申请,根据申请的内容信息,自动建立一条责任链,然后就可以开始流转了。
2. 类图(Class Diagram)
- Handler:定义处理请求的接口,并且实现后继链(successor)
3. 实现(Implementation)
I 校验规则案例
首先,我们要定义流程上节点的基类:
public abstract class RuleHandler {// 后继节点protected RuleHandler successor;public abstract void apply(Context context);public void setSuccessor(RuleHandler successor) {this.successor = successor;}public RuleHandler getSuccessor() {return successor;}}
接下来,我们需要定义具体的每个节点了。
校验用户是否是新用户:
public class NewUserRuleHandler extends RuleHandler {
public void apply(Context context) {
if (context.isNewUser()) {
// 如果有后继节点的话,传递下去
if (this.getSuccessor() != null) {
this.getSuccessor().apply(context);
}
} else {
throw new RuntimeException("该活动仅限新用户参与");
}
}
}
校验用户所在地区是否可以参与:
public class LocationRuleHandler extends RuleHandler {
public void apply(Context context) {
boolean allowed = activityService.isSupportedLocation(context.getLocation);
if (allowed) {
if (this.getSuccessor() != null) {
this.getSuccessor().apply(context);
}
} else {
throw new RuntimeException("非常抱歉,您所在的地区无法参与本次活动");
}
}
}
校验奖品是否已领完:
public class LimitRuleHandler extends RuleHandler {
public void apply(Context context) {
int remainedTimes = activityService.queryRemainedTimes(context); // 查询剩余奖品
if (remainedTimes > 0) {
if (this.getSuccessor() != null) {
this.getSuccessor().apply(userInfo);
}
} else {
throw new RuntimeException("您来得太晚了,奖品被领完了");
}
}
}
客户端:
public class Client {
public static void main(String[] args) {
RuleHandler newUserHandler = new NewUserRuleHandler();
RuleHandler locationHandler = new LocationRuleHandler();
RuleHandler limitHandler = new LimitRuleHandler();
// 假设本次活动仅校验地区和奖品数量,不校验新老用户
locationHandler.setSuccessor(limitHandler);
locationHandler.apply(context);
}
}
先定义好一个链表,然后在通过任意一节点后,如果此节点有后继节点,那么传递下去。
至于它和我们前面说的用一个 List 存放需要执行的规则的做法有什么异同,留给读者自己琢磨吧。
II 处理规则案例
[ Handler ]
public abstract class Handler {
protected Handler successor;
public Handler(Handler successor) {
this.successor = successor;
}
protected abstract void handleRequest(Request request);
}
[ ConcreteHandler ]
public class ConcreteHandlerA 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 ConcreteHandlerA");
return;
}
if (successor != null) {
successor.handleRequest(request);
}
}
}
public class ConcreteHandlerB 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 ConcreteHandlerB");
return;
}
if (successor != null) {
successor.handleRequest(request);
}
}
}
@Get
public class Request {
private RequestType type;
private String name;
//...设置 Get 函数
public Request(RequestType type, String name) {
this.type = type;
this.name = name;
}
}
public enum RequestType {
TYPE1, TYPE2
}
客户端:
public class Client {
public static void main(String[] args) {
// 处理规则链 ConcreteHandlerB -> ConcreteHandlerA -> null
Handler handler1 = new ConcreteHandlerA(null);
Handler handler2 = new ConcreteHandlerB(handler1);
Request requestA = new Request(RequestType.TYPE1, "requestA");
Request requestB = new Request(RequestType.TYPE2, "requestB");
//处理从头部开始处理
handler2.handleRequest(request1);
handler2.handleRequest(request2);
}
}
输出:
request1 is handle by ConcreteHandlerA
request2 is handle by ConcreteHandlerB
