基础编程学习快乐每一天
首页
留言
Siddim.com
当前位置:
首页
>
编程知识库
>
后端开发知识
>
设计模式是什么鬼(责任链)
设计模式是什么鬼(责任链)
阅读
1
2018-11-12
//本文作者:凸凹里歐
//本文收录菜单栏:《设计模式是什么鬼》专栏中
曾经有这么一些零散的功能节点,他们各自承担各自的义务,分工明确,各司其职。为了更高效,更完整地解决客户的问题,他们发扬团队精神,互相串联起来形成一个有序的责任传递链表,于是责任链模式诞生了。当然,它的结构也不一定非得是链表,甚至可以是树型分叉结构,这要根据业务场景看怎样去灵活运用,但其核心意义是为了处理某种连续的流程,并确保业务一定能走到相应的责任节点上并得到相应的处理。
说到这里想必大家已经想到了工作流吧?对,企事业单位中通常为了完成某项日常任务,通常要制定一些工作流程,按步骤拆分,并组织好各个环节中的逻辑关系及走向,这样才能更高效、更规范地完成任务。
根据以上流程图,我们来做一个最简单的例子。假设某公司针对出差报销业务制定审批流程,有三个审批角色分别是员工(
1000
元权限)、经理(
5000
元权限)、以及
CEO
(
10000
元权限),各审批人代码如下。
%
201public
%
20class
%
20Staff
%
20
%
7B
%
0A
%
202
%
0A
%
203
%
20
%
20
%
20
%
20private
%
20String
%
20name
;%
0A
%
204
%
0A
%
205
%
20
%
20
%
20
%
20public
%
20Staff
(
String
%
20name
)%
20
%
7B
%
0A
%
206
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20this
.
name
%
20
=%
20name
;%
0A
%
207
%
20
%
20
%
20
%
20
%
7D
%
0A
%
208
%
0A
%
209
%
20
%
20
%
20
%
20public
%
20boolean
%
20approve
(
int
%
20amount
)%
20
%
7B
%
0A10
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20if
%
20
(
amount
%
20
&
lt
;=%
201000
)%
20
%
7B
%
0A11
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
println
(%
22
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
E9
%
80
%
9A
%
E8
%
BF
%
87
%
E3
%
80
%
82
%
E3
%
80
%
90
%
E5
%
91
%
98
%
E5
%
B7
%
A5
%
EF
%
BC
%
9A
%
22
%
20
%
20name
%
20
%
20
%
22
%
E3
%
80
%
91
%
22
);%
0A12
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20return
%
20true
;%
0A13
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
7D
%
20else
%
20
%
7B
%
0A14
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
println
(%
22
%
E6
%
97
%
A0
%
E6
%
9D
%
83
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
EF
%
BC
%
8C
%
E8
%
AF
%
B7
%
E6
%
89
%
BE
%
E4
%
B8
%
8A
%
E7
%
BA
%
A7
%
E3
%
80
%
82
%
E3
%
80
%
90
%
E5
%
91
%
98
%
E5
%
B7
%
A5
%
EF
%
BC
%
9A
%
22
%
20
%
20name
%
20
%
20
%
22
%
E3
%
80
%
91
%
22
);%
0A15
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20return
%
20false
;%
0A16
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
7D
%
0A17
%
20
%
20
%
20
%
20
%
7D
%
0A18
%
0A19
%
7D
%
0A
%
201public
%
20class
%
20Manager
%
20
%
7B
%
0A
%
202
%
0A
%
203
%
20
%
20
%
20
%
20private
%
20String
%
20name
;%
0A
%
204
%
0A
%
205
%
20
%
20
%
20
%
20public
%
20Manager
(
String
%
20name
)%
20
%
7B
%
0A
%
206
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20this
.
name
%
20
=%
20name
;%
0A
%
207
%
20
%
20
%
20
%
20
%
7D
%
0A
%
208
%
0A
%
209
%
20
%
20
%
20
%
20public
%
20boolean
%
20approve
(
int
%
20amount
)%
20
%
7B
%
0A10
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20if
%
20
(
amount
%
20
&
lt
;=%
205000
)%
20
%
7B
%
0A11
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
println
(%
22
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
E9
%
80
%
9A
%
E8
%
BF
%
87
%
E3
%
80
%
82
%
E3
%
80
%
90
%
E7
%
BB
%
8F
%
E7
%
90
%
86
%
EF
%
BC
%
9A
%
22
%
20
%
20name
%
20
%
20
%
22
%
E3
%
80
%
91
%
22
);%
0A12
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20return
%
20true
;%
0A13
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
7D
%
20else
%
20
%
7B
%
0A14
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
println
(%
22
%
E6
%
97
%
A0
%
E6
%
9D
%
83
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
EF
%
BC
%
8C
%
E8
%
AF
%
B7
%
E6
%
89
%
BE
%
E4
%
B8
%
8A
%
E7
%
BA
%
A7
%
E3
%
80
%
82
%
E3
%
80
%
90
%
E7
%
BB
%
8F
%
E7
%
90
%
86
%
EF
%
BC
%
9A
%
22
%
20
%
20name
%
20
%
20
%
22
%
E3
%
80
%
91
%
22
);%
0A15
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20return
%
20false
;%
0A16
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
7D
%
0A17
%
20
%
20
%
20
%
20
%
7D
%
0A18
%
0A19
%
7D
%
0A
%
201public
%
20class
%
20CEO
%
20
%
7B
%
0A
%
202
%
0A
%
203
%
20
%
20
%
20
%
20private
%
20String
%
20name
;%
0A
%
204
%
0A
%
205
%
20
%
20
%
20
%
20public
%
20CEO
(
String
%
20name
)%
20
%
7B
%
0A
%
206
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20this
.
name
%
20
=%
20name
;%
0A
%
207
%
20
%
20
%
20
%
20
%
7D
%
0A
%
208
%
0A
%
209
%
20
%
20
%
20
%
20public
%
20boolean
%
20approve
(
int
%
20amount
)%
20
%
7B
%
0A10
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20if
%
20
(
amount
%
20
&
lt
;=%
2010000
)%
20
%
7B
%
0A11
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
println
(%
22
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
E9
%
80
%
9A
%
E8
%
BF
%
87
%
E3
%
80
%
82
%
E3
%
80
%
90CEO
%
EF
%
BC
%
9A
%
22
%
20
%
20name
%
20
%
20
%
22
%
E3
%
80
%
91
%
22
);%
0A12
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20return
%
20true
;%
0A13
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
7D
%
20else
%
20
%
7B
%
0A14
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
println
(%
22
%
E9
%
A9
%
B3
%
E5
%
9B
%
9E
%
E7
%
94
%
B3
%
E8
%
AF
%
B7
%
E3
%
80
%
82
%
E3
%
80
%
90CEO
%
EF
%
BC
%
9A
%
22
%
20
%
20name
%
20
%
20
%
22
%
E3
%
80
%
91
%
22
);%
0A15
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20return
%
20false
;%
0A16
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
7D
%
0A17
%
20
%
20
%
20
%
20
%
7D
%
0A18
%
0A19
%
7D
%
0A
好了,审批人们定义完毕,逻辑非常简单缜密,如果超过审批金额最大权限则打回去,开始写申请人客户端类。
%
201public
%
20class
%
20Client
%
20
%
7B
%
0A
%
202
%
20
%
20
%
20
%
20public
%
20static
%
20void
%
20main
(
String
%
5B
%
5D
%
20args
)%
20
%
7B
%
0A
%
203
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20int
%
20amount
%
20
=%
2010000
;//%
E5
%
87
%
BA
%
E5
%
B7
%
AE
%
E8
%
8A
%
B1
%
E8
%
B4
%
B910000
%
E5
%
85
%
83
%
0A
%
204
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
//%
20
%
E5
%
85
%
88
%
E6
%
89
%
BE
%
E5
%
91
%
98
%
E5
%
B7
%
A5
%
E5
%
BC
%
A0
%
E9
%
A3
%
9E
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
0A
%
205
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20Staff
%
20staff
%
20
=%
20new
%
20Staff
(%
22
%
E5
%
BC
%
A0
%
E9
%
A3
%
9E
%
22
);%
0A
%
206
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20if
%
20
(!
staff
.
approve
(
amount
))%
20
%
7B
%
0A
%
207
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
//%
E8
%
A2
%
AB
%
E6
%
8B
%
92
%
EF
%
BC
%
8C
%
E6
%
89
%
BE
%
E5
%
85
%
B3
%
E4
%
BA
%
8C
%
E7
%
88
%
B7
%
E9
%
97
%
AE
%
E9
%
97
%
AE
%
E3
%
80
%
82
%
0A
%
208
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20Manager
%
20manager
%
20
=%
20new
%
20Manager
(%
22
%
E5
%
85
%
B3
%
E7
%
BE
%
BD
%
22
);%
0A
%
209
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20if
%
20
(!
manager
.
approve
(
amount
))%
20
%
7B
%
0A10
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
//%
E8
%
BF
%
98
%
E6
%
98
%
AF
%
E8
%
A2
%
AB
%
E6
%
8B
%
92
%
EF
%
BC
%
8C
%
E5
%
8F
%
AA
%
E8
%
83
%
BD
%
E6
%
89
%
BE
%
E8
%
80
%
81
%
E5
%
A4
%
A7
%
E4
%
BA
%
86
%
E3
%
80
%
82
%
0A11
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20CEO
%
20ceo
%
20
=%
20new
%
20CEO
(%
22
%
E5
%
88
%
98
%
E5
%
A4
%
87
%
22
);%
0A12
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20ceo
.
approve
(
amount
);%
0A13
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
7D
%
0A14
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
7D
%
0A15
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
/***********************%
0A16
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E6
%
97
%
A0
%
E6
%
9D
%
83
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
EF
%
BC
%
8C
%
E8
%
AF
%
B7
%
E6
%
89
%
BE
%
E4
%
B8
%
8A
%
E7
%
BA
%
A7
%
E3
%
80
%
82
%
E3
%
80
%
90
%
E5
%
91
%
98
%
E5
%
B7
%
A5
%
EF
%
BC
%
9A
%
E5
%
BC
%
A0
%
E9
%
A3
%
9E
%
E3
%
80
%
91
%
0A17
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E6
%
97
%
A0
%
E6
%
9D
%
83
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
EF
%
BC
%
8C
%
E8
%
AF
%
B7
%
E6
%
89
%
BE
%
E4
%
B8
%
8A
%
E7
%
BA
%
A7
%
E3
%
80
%
82
%
E3
%
80
%
90
%
E7
%
BB
%
8F
%
E7
%
90
%
86
%
EF
%
BC
%
9A
%
E5
%
85
%
B3
%
E7
%
BE
%
BD
%
E3
%
80
%
91
%
0A18
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
E9
%
80
%
9A
%
E8
%
BF
%
87
%
E3
%
80
%
82
%
E3
%
80
%
90CEO
%
EF
%
BC
%
9A
%
E5
%
88
%
98
%
E5
%
A4
%
87
%
E3
%
80
%
91
%
0A19
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
***********************/%
0A20
%
20
%
20
%
20
%
20
%
7D
%
0A21
%
7D
%
0A
功夫不负有心人,跑了三个地方找了三个人,一万元的大额报销单终于被大老板审批了。然而,大家有没有发现问题?我们走的审批流程好像有点过于复杂了,找这个不行那个不同意,跑来跑去的好像自己有点像是被踢皮球的感觉。此外,如果我们后期要优化完善此工作流程,或是添加新的审批角色进来,那就得不停地修改此处的逻辑,最终的修改结果会是?
乱了,全乱套了,我们终将被淹没在一堆复杂的审批流程中,跑断腿也找不到门路。这显然是违反设计模式原则的,我们必须进行重构。我们观察此类中的审批逻辑,这显然就是一个链式结构,审批人之间环环相扣,对于自己无法处理的申请,会像被踢皮球似的传给上级,直到某人解决此申请,对员工张飞来说,他只知道自己传球给关羽了,仅此而已。
进一步分析,审批人肯定是不同的角色,并且每个角色的审批逻辑会有区别,所以我们得把这些角色的审批逻辑分开来写,对每个角色的责任范围我们进行定义,我只懂自己怎么审批(责任),我处理不了的我递交给上层(链条),开始重构,先抽象出一个审批人类。
%
201public
%
20abstract
%
20class
%
20Approver
%
20
%
7B
//%
20
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
E4
%
BA
%
BA
%
E6
%
8A
%
BD
%
E8
%
B1
%
A1
%
E7
%
B1
%
BB
%
0A
%
202
%
0A
%
203
%
20
%
20
%
20
%
20protected
%
20String
%
20name
;//%
20
%
E6
%
8A
%
BD
%
E8
%
B1
%
A1
%
E5
%
87
%
BA
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
E4
%
BA
%
BA
%
E7
%
9A
%
84
%
E5
%
A7
%
93
%
E5
%
90
%
8D
%
E3
%
80
%
82
%
0A
%
204
%
20
%
20
%
20
%
20protected
%
20Approver
%
20nextApprover
;//%
20
%
E4
%
B8
%
8B
%
E4
%
B8
%
80
%
E4
%
B8
%
AA
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
E4
%
BA
%
BA
%
EF
%
BC
%
8C
%
E6
%
9B
%
B4
%
E9
%
AB
%
98
%
E7
%
BA
%
A7
%
E5
%
88
%
AB
%
E9
%
A2
%
86
%
E5
%
AF
%
BC
%
E3
%
80
%
82
%
0A
%
205
%
0A
%
206
%
20
%
20
%
20
%
20public
%
20Approver
(
String
%
20name
)%
20
%
7B
%
0A
%
207
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20this
.
name
%
20
=%
20name
;%
0A
%
208
%
20
%
20
%
20
%
20
%
7D
%
0A
%
209
%
0A10
%
20
%
20
%
20
%
20protected
%
20Approver
%
20setNextApprover
(
Approver
%
20nextApprover
)%
20
%
7B
%
0A11
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20this
.
nextApprover
%
20
=%
20nextApprover
;%
0A12
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20return
%
20this
.
nextApprover
;//%
20
%
E8
%
BF
%
94
%
E5
%
9B
%
9E
%
E4
%
B8
%
8B
%
E4
%
B8
%
AA
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
E4
%
BA
%
BA
%
EF
%
BC
%
8C
%
E9
%
93
%
BE
%
E5
%
BC
%
8F
%
E7
%
BC
%
96
%
E7
%
A8
%
8B
%
E3
%
80
%
82
%
0A13
%
20
%
20
%
20
%
20
%
7D
%
0A14
%
0A15
%
20
%
20
%
20
%
20public
%
20abstract
%
20void
%
20approve
(
int
%
20amount
);//%
20
%
E6
%
8A
%
BD
%
E8
%
B1
%
A1
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
E6
%
96
%
B9
%
E6
%
B3
%
95
%
E7
%
94
%
B1
%
E5
%
85
%
B7
%
E4
%
BD
%
93
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
E4
%
BA
%
BA
%
E5
%
AD
%
90
%
E7
%
B1
%
BB
%
E5
%
AE
%
9E
%
E7
%
8E
%
B0
%
0A16
%
7D
注意第
4
行,审批人只认识自己的领导,所以会持有下一级领导的引用,同时第
10
行的代码用于把领导注入进来。第
15
行是我们的审批方法了,但每个角色审批逻辑会有区别,所以这里进行抽象,并由具体的审批角色子类去实现,先从员工看起。
%
201public
%
20class
%
20Staff
%
20extends
%
20Approver
%
20
%
7B
%
0A
%
202
%
0A
%
203
%
20
%
20
%
20
%
20public
%
20Staff
(
String
%
20name
)%
20
%
7B
%
0A
%
204
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20super
(
name
);%
0A
%
205
%
20
%
20
%
20
%
20
%
7D
%
0A
%
206
%
0A
%
207
%
20
%
20
%
20
%
20
@
Override
%
0A
%
208
%
20
%
20
%
20
%
20public
%
20void
%
20approve
(
int
%
20amount
)%
20
%
7B
%
0A
%
209
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20if
%
20
(
amount
%
20
&
lt
;=%
201000
)%
20
%
7B
%
0A10
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
println
(%
22
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
E9
%
80
%
9A
%
E8
%
BF
%
87
%
E3
%
80
%
82
%
E3
%
80
%
90
%
E5
%
91
%
98
%
E5
%
B7
%
A5
%
EF
%
BC
%
9A
%
22
%
20
%
20name
%
20
%
20
%
22
%
E3
%
80
%
91
%
22
);%
0A11
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
7D
%
20else
%
20
%
7B
%
0A12
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
println
(%
22
%
E6
%
97
%
A0
%
E6
%
9D
%
83
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
EF
%
BC
%
8C
%
E5
%
8D
%
87
%
E7
%
BA
%
A7
%
E5
%
A4
%
84
%
E7
%
90
%
86
%
E3
%
80
%
82
%
E3
%
80
%
90
%
E5
%
91
%
98
%
E5
%
B7
%
A5
%
EF
%
BC
%
9A
%
22
%
20
%
20name
%
20
%
20
%
22
%
E3
%
80
%
91
%
22
);%
0A13
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20this
.
nextApprover
.
approve
(
amount
);%
0A14
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
7D
%
0A15
%
20
%
20
%
20
%
20
%
7D
%
0A16
%
0A17
%
7D
很简单,员工类继承了审批角色类,第
9
行申明审批权限为
1000
元,重点在于第
13
行这里调用了自己上级领导的审批方法,显然这里是自己处理不了的申请单了。大同小异,再重构经理及
CEO
审批角色类。
%
201public
%
20class
%
20Manager
%
20extends
%
20Approver
%
20
%
7B
%
0A
%
202
%
0A
%
203
%
20
%
20
%
20
%
20public
%
20Manager
(
String
%
20name
)%
20
%
7B
%
0A
%
204
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20super
(
name
);%
0A
%
205
%
20
%
20
%
20
%
20
%
7D
%
0A
%
206
%
0A
%
207
%
20
%
20
%
20
%
20
@
Override
%
0A
%
208
%
20
%
20
%
20
%
20public
%
20void
%
20approve
(
int
%
20amount
)%
20
%
7B
%
0A
%
209
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20if
%
20
(
amount
%
20
&
lt
;=%
205000
)%
20
%
7B
%
0A10
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
println
(%
22
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
E9
%
80
%
9A
%
E8
%
BF
%
87
%
E3
%
80
%
82
%
E3
%
80
%
90
%
E7
%
BB
%
8F
%
E7
%
90
%
86
%
EF
%
BC
%
9A
%
22
%
20
%
20name
%
20
%
20
%
22
%
E3
%
80
%
91
%
22
);%
0A11
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
7D
%
20else
%
20
%
7B
%
0A12
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
println
(%
22
%
E6
%
97
%
A0
%
E6
%
9D
%
83
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
EF
%
BC
%
8C
%
E5
%
8D
%
87
%
E7
%
BA
%
A7
%
E5
%
A4
%
84
%
E7
%
90
%
86
%
E3
%
80
%
82
%
E3
%
80
%
90
%
E7
%
BB
%
8F
%
E7
%
90
%
86
%
EF
%
BC
%
9A
%
22
%
20
%
20name
%
20
%
20
%
22
%
E3
%
80
%
91
%
22
);%
0A13
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20this
.
nextApprover
.
approve
(
amount
);%
0A14
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
7D
%
0A15
%
20
%
20
%
20
%
20
%
7D
%
0A16
%
0A17
%
7D
%
0A
%
201public
%
20class
%
20CEO
%
20extends
%
20Approver
%
20
%
7B
%
0A
%
202
%
0A
%
203
%
20
%
20
%
20
%
20public
%
20CEO
(
String
%
20name
)%
20
%
7B
%
0A
%
204
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20super
(
name
);%
0A
%
205
%
20
%
20
%
20
%
20
%
7D
%
0A
%
206
%
0A
%
207
%
20
%
20
%
20
%
20
@
Override
%
0A
%
208
%
20
%
20
%
20
%
20public
%
20void
%
20approve
(
int
%
20amount
)%
20
%
7B
%
0A
%
209
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20if
%
20
(
amount
%
20
&
lt
;=%
2010000
)%
20
%
7B
%
0A10
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
println
(%
22
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
E9
%
80
%
9A
%
E8
%
BF
%
87
%
E3
%
80
%
82
%
E3
%
80
%
90CEO
%
EF
%
BC
%
9A
%
22
%
20
%
20name
%
20
%
20
%
22
%
E3
%
80
%
91
%
22
);%
0A11
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
7D
%
20else
%
20
%
7B
%
0A12
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
println
(%
22
%
E9
%
A9
%
B3
%
E5
%
9B
%
9E
%
E7
%
94
%
B3
%
E8
%
AF
%
B7
%
E3
%
80
%
82
%
E3
%
80
%
90CEO
%
EF
%
BC
%
9A
%
22
%
20
%
20name
%
20
%
20
%
22
%
E3
%
80
%
91
%
22
);%
0A13
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
7D
%
0A14
%
20
%
20
%
20
%
20
%
7D
%
0A15
%
0A16
%
7D
%
0A
CEO
类作为链条的尾巴,也就是最高级别,第
12
行的越权逻辑会最终拒绝申请单。很简单吧?我们生成一下这个链条,并从员工开始传递申请单。
%
201public
%
20class
%
20Client
%
20
%
7B
%
0A
%
202
%
20
%
20
%
20
%
20public
%
20static
%
20void
%
20main
(
String
%
5B
%
5D
%
20args
)%
20
%
7B
%
0A
%
203
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20Approver
%
20flightJohn
%
20
=%
20new
%
20Staff
(%
22
%
E5
%
BC
%
A0
%
E9
%
A3
%
9E
%
22
);%
0A
%
204
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20flightJohn
.
setNextApprover
(
new
%
20Manager
(%
22
%
E5
%
85
%
B3
%
E7
%
BE
%
BD
%
22
)).
setNextApprover
(
new
%
20CEO
(%
22
%
E5
%
88
%
98
%
E5
%
A4
%
87
%
22
));%
0A
%
205
%
0A
%
206
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
//%
E9
%
AB
%
98
%
E5
%
B1
%
82
%
E6
%
8E
%
A5
%
E8
%
A7
%
A6
%
E4
%
B8
%
8D
%
E5
%
88
%
B0
%
E4
%
B9
%
9F
%
E6
%
B2
%
A1
%
E5
%
BF
%
85
%
E8
%
A6
%
81
%
E6
%
8E
%
A5
%
E8
%
A7
%
A6
%
EF
%
BC
%
8C
%
E7
%
9B
%
B4
%
E6
%
8E
%
A5
%
E6
%
89
%
BE
%
E5
%
91
%
98
%
E5
%
B7
%
A5
%
E5
%
BC
%
A0
%
E9
%
A3
%
9E
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
E3
%
80
%
82
%
0A
%
207
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20flightJohn
.
approve
(
1000
);%
0A
%
208
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
/***********************%
0A
%
209
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
E9
%
80
%
9A
%
E8
%
BF
%
87
%
E3
%
80
%
82
%
E3
%
80
%
90
%
E5
%
91
%
98
%
E5
%
B7
%
A5
%
EF
%
BC
%
9A
%
E5
%
BC
%
A0
%
E9
%
A3
%
9E
%
E3
%
80
%
91
%
0A10
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
***********************/%
0A11
%
0A12
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20flightJohn
.
approve
(
4000
);%
0A13
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
/***********************%
0A14
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E6
%
97
%
A0
%
E6
%
9D
%
83
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
EF
%
BC
%
8C
%
E5
%
8D
%
87
%
E7
%
BA
%
A7
%
E5
%
A4
%
84
%
E7
%
90
%
86
%
E3
%
80
%
82
%
E3
%
80
%
90
%
E5
%
91
%
98
%
E5
%
B7
%
A5
%
EF
%
BC
%
9A
%
E5
%
BC
%
A0
%
E9
%
A3
%
9E
%
E3
%
80
%
91
%
0A15
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
E9
%
80
%
9A
%
E8
%
BF
%
87
%
E3
%
80
%
82
%
E3
%
80
%
90
%
E7
%
BB
%
8F
%
E7
%
90
%
86
%
EF
%
BC
%
9A
%
E5
%
85
%
B3
%
E7
%
BE
%
BD
%
E3
%
80
%
91
%
0A16
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
***********************/%
0A17
%
0A18
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20flightJohn
.
approve
(
9000
);%
0A19
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
/***********************%
0A20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E6
%
97
%
A0
%
E6
%
9D
%
83
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
EF
%
BC
%
8C
%
E5
%
8D
%
87
%
E7
%
BA
%
A7
%
E5
%
A4
%
84
%
E7
%
90
%
86
%
E3
%
80
%
82
%
E3
%
80
%
90
%
E5
%
91
%
98
%
E5
%
B7
%
A5
%
EF
%
BC
%
9A
%
E5
%
BC
%
A0
%
E9
%
A3
%
9E
%
E3
%
80
%
91
%
0A21
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E6
%
97
%
A0
%
E6
%
9D
%
83
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
EF
%
BC
%
8C
%
E5
%
8D
%
87
%
E7
%
BA
%
A7
%
E5
%
A4
%
84
%
E7
%
90
%
86
%
E3
%
80
%
82
%
E3
%
80
%
90
%
E7
%
BB
%
8F
%
E7
%
90
%
86
%
EF
%
BC
%
9A
%
E5
%
85
%
B3
%
E7
%
BE
%
BD
%
E3
%
80
%
91
%
0A22
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
E9
%
80
%
9A
%
E8
%
BF
%
87
%
E3
%
80
%
82
%
E3
%
80
%
90CEO
%
EF
%
BC
%
9A
%
E5
%
88
%
98
%
E5
%
A4
%
87
%
E3
%
80
%
91
%
0A23
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
***********************/%
0A24
%
0A25
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20flightJohn
.
approve
(
88000
);%
0A26
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
/***********************%
0A27
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E6
%
97
%
A0
%
E6
%
9D
%
83
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
EF
%
BC
%
8C
%
E5
%
8D
%
87
%
E7
%
BA
%
A7
%
E5
%
A4
%
84
%
E7
%
90
%
86
%
E3
%
80
%
82
%
E3
%
80
%
90
%
E5
%
91
%
98
%
E5
%
B7
%
A5
%
EF
%
BC
%
9A
%
E5
%
BC
%
A0
%
E9
%
A3
%
9E
%
E3
%
80
%
91
%
0A28
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E6
%
97
%
A0
%
E6
%
9D
%
83
%
E5
%
AE
%
A1
%
E6
%
89
%
B9
%
EF
%
BC
%
8C
%
E5
%
8D
%
87
%
E7
%
BA
%
A7
%
E5
%
A4
%
84
%
E7
%
90
%
86
%
E3
%
80
%
82
%
E3
%
80
%
90
%
E7
%
BB
%
8F
%
E7
%
90
%
86
%
EF
%
BC
%
9A
%
E5
%
85
%
B3
%
E7
%
BE
%
BD
%
E3
%
80
%
91
%
0A29
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E9
%
A9
%
B3
%
E5
%
9B
%
9E
%
E7
%
94
%
B3
%
E8
%
AF
%
B7
%
E3
%
80
%
82
%
E3
%
80
%
90CEO
%
EF
%
BC
%
9A
%
E5
%
88
%
98
%
E5
%
A4
%
87
%
E3
%
80
%
91
%
0A30
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
***********************/%
0A31
%
20
%
20
%
20
%
20
%
7D
%
0A32
%
7D
%
0A
这里注意第
4
行的代码对责任链进行构造(其实这里我们还可以交由工作流工厂去构造完成,读者可以自己实践练习),从员工开始一直到
CEO
结束。之后的业务就非常简单了,直接递单给员工张飞,审批流程便魔法般地启动了,审批单在这个责任链条上层层递交,最终给出结果。
至此,申请人与审批人实现了解耦,我们只需递单送给责任链即可,申请人不必再关心每个处理细节,只需交给接口人张飞处理就妥了。使用了责任链模式后的代码看起来非常简洁,各个角色的责任划分非常明确并且被分开定义到了每个角色类中,再把他们串起来去调用,一气呵成。后期如果再继续添加新的角色只需要添加新角色类并加入链条即可,链条的随意伸缩,灵活的可伸缩性,完美的可扩展性。挂上这条钛合金项链,维护世界和平的责任就交给你了!
在实际应用中,我们切勿生搬硬套,还需根据实际需求场景进行灵活运用,就拿工业现代化生产线举例,这个其实也类似责任链模式,但不同之处在于其组装工作是必须经过每个组装节点处理的,从头到尾的全链处理而不能中途退出,读者朋友可以自己写代码练习,实践与思考要相结合并循环往复,二者都非常重要。
点击图片加入
Spring
交流群
↓↓↓
看完本文有收获?请转发分享给更多人
以上数据来源于网络,如有侵权,请联系删除。
上一篇:
面试官:你能简单说说 SpringMVC 的执行原理吗?
下一篇:
面试官:String长度有限制吗?是多少?还好我看过
评论
(0)
提交
类别
基础编程学习
HTML
PHP
Python
编程知识库
后端开发知识
热门文章
Java并发中的同步容器与并发容器,你了解多少?
Innodb中的事务隔离级别和锁的关系,难倒一半面试者!
SpringBoot + minio实现分片上传、秒传、续传
面试官:你知道消息队列如何保证数据不丢失吗?
JAVA知识 Java8新特性
面试官:谈谈为什么要限流,有哪些限流方案?
说说动态代理与静态代理区别
面试官:思考Tomcat 类加载器为什么要违背双亲委派模型?
boot-admin 基于SpringBoot的后台权限管理系统,可作为脚手架,用于快速搭建项目
SpringBoot+Vue+App+硬件实现智能家居系统项目