行为型模式:责任链模式

LieBrother原文
行为型模式:责任链模式

景色

十一大行为型模式之四:责任链模式。

简介

姓名 :责任链模式

英文名 :Chain of Responsibility Pattern

价值观 :责任归我

个人介绍
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.Chain the receiving objects and pass the request along the chain until an object handles it.
使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
(来自《设计模式之禅》)

你要的故事

快要金三银四了,很多同学蠢蠢欲动想要去外面看看世界,而大家有没有提前了解各大企业的面试流程呢?这里我就给大家科普一下大多数互联网企业的面试流程,正好责任链模式用得上。

在互联网企业中,程序员这个岗位的招聘流程大同小异,而一般至少都会有 3 轮面试,分别是 2 轮技术面和 1 轮 HR 面。而这几轮面试都是层层递进的,最开始面试一般是组长面试,通过之后就是部门领导面试,再通过之后就是 HR 面试,HR 面试通过之后就可以成功拿到 Offer 了。

故事从小明参加某公司的面试开始,某公司的招聘流程就是上面说的 3 轮面试。招聘流程的面试官分别是:第一面是组长老刚,第二面是部门经理老孙,第三面也就是终面是 HR 老刘。为什么说这个场景符合责任链模式呢?首先不管是组长还是部门经理还是 HR,他们都作为面试官,面试官赋予他们的权利是去面试来公司面试的同学,而面试的结果是可传递性的,也就是如果面试通过,就会到下一轮面试,最终成为一条传递链。我们用代码模拟这个过程。

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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
public class ChainOfResponsibilityTest {

public static void main(String[] args) {
Interviewee interviewee = new Interviewee("小明");
TeamLeader teamLeader = new TeamLeader("老刚");
DepartMentManager departMentManager = new DepartMentManager("老孙");
HR hr = new HR("老刘");
// 设置面试流程
teamLeader.setNextInterviewer(departMentManager);
departMentManager.setNextInterviewer(hr);
// 开始面试
teamLeader.handleInterview(interviewee);
}

}

/**
* 面试者
*/
class Interviewee {

private String name;

private boolean teamLeaderOpinion;
private boolean departMentManagerOpinion;
private boolean hrOpinion;

public Interviewee(String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public boolean isTeamLeaderOpinion() {
return teamLeaderOpinion;
}

public void setTeamLeaderOpinion(boolean teamLeaderOpinion) {
this.teamLeaderOpinion = teamLeaderOpinion;
}

public boolean isDepartMentManagerOpinion() {
return departMentManagerOpinion;
}

public void setDepartMentManagerOpinion(boolean departMentManagerOpinion) {
this.departMentManagerOpinion = departMentManagerOpinion;
}

public boolean isHrOpinion() {
return hrOpinion;
}

public void setHrOpinion(boolean hrOpinion) {
this.hrOpinion = hrOpinion;
}
}

/**
* 面试官
*/
abstract class Interviewer {

protected String name;
protected Interviewer nextInterviewer;

public Interviewer(String name) {
this.name = name;
}

public Interviewer setNextInterviewer(Interviewer nextInterviewer) {
this.nextInterviewer = nextInterviewer;
return this.nextInterviewer;
}

public abstract void handleInterview(Interviewee interviewee);

}

/**
* 组长
*/
class TeamLeader extends Interviewer {

public TeamLeader(String name) {
super(name);
}

@Override
public void handleInterview(Interviewee interviewee) {
System.out.println("组长[" + this.name + "]面试[" + interviewee.getName() + "]同学");
interviewee.setTeamLeaderOpinion(new Random().nextBoolean());
if (interviewee.isTeamLeaderOpinion()) {
System.out.println("[" + interviewee.getName() + "]同学组长轮面试通过");
this.nextInterviewer.handleInterview(interviewee);
} else {
System.out.println("[" + interviewee.getName() + "]同学组长轮面试不通过");
}
}
}

/**
* 部门经理
*/
class DepartMentManager extends Interviewer {

public DepartMentManager(String name) {
super(name);
}

@Override
public void handleInterview(Interviewee interviewee) {
System.out.println("部门经理[" + this.name + "]面试[" + interviewee.getName() + "]同学");
interviewee.setDepartMentManagerOpinion(new Random().nextBoolean());
if (interviewee.isDepartMentManagerOpinion()) {
System.out.println("[" + interviewee.getName() + "]同学部门经理轮面试通过");
this.nextInterviewer.handleInterview(interviewee);
} else {
System.out.println("[" + interviewee.getName() + "]同学部门经理轮面试不通过");
}
}
}

/**
* HR
*/
class HR extends Interviewer {

public HR(String name) {
super(name);
}

@Override
public void handleInterview(Interviewee interviewee) {
System.out.println("HR[" + this.name + "]面试[" + interviewee.getName() + "]同学");
interviewee.setHrOpinion(new Random().nextBoolean());
if (interviewee.isHrOpinion()) {
System.out.println("[" + interviewee.getName() + "]同学HR轮面试通过, 恭喜拿到 Offer");
} else {
System.out.println("[" + interviewee.getName() + "]同学HR轮面试不通过");
}
}
}

打印结果:
组长[老刚]面试[小明]同学
[小明]同学组长轮面试通过
部门经理[老孙]面试[小明]同学
[小明]同学部门经理轮面试通过
HR[老刘]面试[小明]同学
[小明]同学HR轮面试通过, 恭喜拿到 Offer

上面代码打印结果是小明通过层层筛选,通过了面试,拿到了 Offer。下面的图来展现这次面试的流程。

流程图

讲解一下代码,Interviewee 是面试者,对于企业来说这个面试者来面试的过程会有 3 个关键标识,就是 3 位面试官对这位面试者的评价,只有都评价好才能通过面试拿到 Offer,所以 Interviewee 类有 3 位面试官的面试结果。Interviewer 是面时官,企业中面试官不是一个职位,而是一个工作,帮企业招到合适的人才,所以它是一个抽象类,有一个抽象方法就是去面试应聘者,具体面试过程又各面试官实现,而因为这个面试会有结果反馈,结果好的会进入下一轮面试,所以会有下一个面试官的对象引用,责任链模式也就在这里体现。TeamLeader、DepartMentManager、HR 则为公司的不同职位,而这些职位当公司需要招聘时,都需要去充当面试官,所以都继承了 Interviewer。这整个过程就构成了责任链模式代码示例,希望在金三银四各位蠢蠢欲动的朋友们都能闯到最后一关拿下 HR 姐姐。

代码:
Chain of Responsibility Pattern

总结

责任链模式很好的把处理的逻辑封装起来,在代码中,我们看到的只是组长面试,但是其实背后隐藏着部门经理和HR的面试。责任链是不是看起来很熟悉?在开发 Java Web 项目的时候是不是有用到过?Filter 过滤器里面就是用责任链模式来实现的。上面代码还用到了另一个模式,不明确指出来了,考验大家学习这些设计模式的效果,知道的同学可以留言说一下。

参考资料:《大话设计模式》、《设计模式之禅》

推荐阅读:

公众号之设计模式系列文章

希望文章对您有所帮助,设计模式系列会持续更新,感兴趣的同学可以关注公众号:LieBrother,第一时间获取文章推送阅读,也可以一起交流,交个朋友。

公众号