Java设计模式学习 - 责任链模式

设计模式-责任链

简单介绍

责任链模式(Chain of Responsibility):使多个对象都有机会处理同一个请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。


举个🌰

一节课堂,有课前、课中和课后,不同老师、不同地点或者不同时间,课堂的内容和实际都有所不同,如果在一个service中写业务逻辑,代码可读性会比较差,别人维护也麻烦,所以使用责任链模式,将每一步分开维护,大概流程如下:

  • 编写课程前、中、后的执行逻辑和回滚逻辑
  • 一个业务结束后,调用下一个业务的执行逻辑
  • 一个业务失败后,调用上一个业务的回滚逻辑

PS:左边的课程和规则是一个整体,责任链真正处理的流程是右边的逻辑。


实现代码

这个例子还用到了工厂方法和单例方法,以及与Spring整合了,各位看官在实际使用中,要根据自身情况,适当的修改。

抽象RuleHandler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/**
* @author JingQ at 2018/9/7
*/
public abstract class AbstractRuleHandler {

/**
* 上一个处理器
*/
private AbstractRuleHandler preHandler;

/**
* 下一个处理器
*/
private AbstractRuleHandler nextHandler;

/**
* 责任链模式
* @param experiment experiment
*/
public void doHandler(Experiment experiment, ClassRule rule) {
try {
doHandleReal(experiment, rule);
} catch (Exception e) {
rollBack(experiment, rule);
return;
}
if (nextHandler != null) {
nextHandler.doHandler(experiment, rule);
}
}

/**
* 回滚策略
* @param experiment experiment
* @param rule rule
*/
public void rollBack(Experiment experiment ,ClassRule rule) {
rollBackReal(experiment, rule);
if (preHandler != null) {
preHandler.rollBack(experiment, rule);
}
}

/**
* 真正处理的逻辑
* @param experiment experiment
* @param rule 规则
*/
public abstract void doHandleReal(Experiment experiment, ClassRule rule);

/**
* 回滚逻辑
* @param experiment experiment
* @param rule 规则
*/
public abstract void rollBackReal(Experiment experiment, ClassRule rule);

public AbstractRuleHandler setPreHandler(AbstractRuleHandler preHandler) {
this.preHandler = preHandler;
return preHandler;
}

public AbstractRuleHandler setNextHandler(AbstractRuleHandler nextHandler) {
this.nextHandler = nextHandler;
nextHandler.setPreHandler(this);
return nextHandler;
}
}

第一个Handler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Service
public class ClassBeginRuleHandler extends AbstractRuleHandler {

@Override
public void doHandleReal(Experiment experiment, ClassRule rule) {
experiment.setName(rule.getRule1());
System.out.println("success rule1 : " + rule.getRule1());
}

@Override
public void rollBackReal(Experiment experiment, ClassRule rule) {
System.out.println("error rule1 : " + rule.getRule1());
}
}

由于第二个与第一个处理一样,就不贴出来了


第三个Handler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Service
public class ClassEndRuleHandler extends AbstractRuleHandler {

@Autowired
private ClassroomService classroomService;

@Override
public void doHandleReal(Experiment experiment, ClassRule rule) {
Classroom classroom = classroomService.getById(experiment.getClassroomId());
if (classroom != null) {
if (StringUtils.equals(classroom.getClassroom(), rule.getRule3())) {
experiment.setClassroomId(classroom.getId());
}
System.out.println(classroom.getClassroom() + "-" + rule.getRule3());
} else {
System.out.println("classroom is null , success rule 3 :" + rule.getRule3());
}
}

@Override
public void rollBackReal(Experiment experiment, ClassRule rule) {
System.out.println("error Rule 3 : " + rule.getRule3());
}
}

工厂整合类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/**
* 工厂方法
* @author JingQ at 2018/9/7
*/
@Service
public class AbstractRuleFactory {

@Autowired
private ClassEndRuleHandler classEndRuleHandler;

@Autowired
private ClassingRuleHandler classingRuleHandler;

@Autowired
private ClassBeginRuleHandler classBeginRuleHandler;

private AbstractRuleHandler ruleHandler;

private AbstractRuleFactory() {
}

// 使用了单例模式
public AbstractRuleHandler getInstance() {
if (ruleHandler == null) {
synchronized (AbstractRuleFactory.class) {
if (ruleHandler == null) {
ruleHandler = classBeginRuleHandler;
ruleHandler.setNextHandler(classingRuleHandler).setNextHandler(classEndRuleHandler);
}
}
}
return ruleHandler;
}
}

执行效果

可以看到,通过factory.getInstance().doHandle(experiment, rule),责任链会根据设定的顺序进行执行,每个业务操作都进行分开了,代码也更加整洁,维护性也更强了。


参考资料

  1. Java设计模式—-责任链模式
  2. Java设计模式应用——责任链模式