java设计模式-责任链模式

责任链模式

1.简述

责任链模式(Chain of Responsibility),行为型设计模式之一。什么是责任链呢?这个链的形式更像是数据结构中的单链表,链中的每个节点都有自己的职责,同时也持有下一个节点的引用,
属于自己职责范围内的请求就自行处理,并完成请求的处理;而不属于的职责就传递给下一个节点。每个节点都是如此循环,直至请求被处理或者已经没有处理节点。

这种设计模式是为了避免请求的发送者和接收者之间的耦合关系,而责任链就是中间的请求处理者,其中可能包括多个有可能处理请求的对象,并将这些对象炼成一条链。这样也使得请求发送者无需关心请求的处理细节和请求的传递。

img

  • Client:客户端,请求的发起者
  • Handler:抽象处理者,声明一个请求方法,并在其中保持一个对下一个处理节点Handler对象的引用
  • ConcreteHandler:具体处理角色,对请求进行处理;如果不能处理则将请求转发给下一个节点对象处理

2.案例实现

场景介绍

以公司正常请假为例,1天以内的假需要客户端部门主管签字,3天以内(不包含3天)需要技术部门主管签字,3天及以上就需要找CEO签字。

首先是假条的类,包含姓名、请假原因和请假时间,使用final声明属性只是为了避免外部修改属性而已。

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
/**
* @ClassName: LeaveNote
* @User: xiaomi
* @Description: //请假条
* @Time: 2019/6/26 0026 下午 1:58
* @email: a1205938863@gmail.com
*/

public class LeaveNote {
private String name;
private String reason;
private int leaveDays;

public LeaveNote(String name, String reason, int leaveDays) {
this.name = name;
this.reason = reason;
this.leaveDays = leaveDays;
}

public String getName() {
return name;
}

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

public String getReason() {
return reason;
}

public void setReason(String reason) {
this.reason = reason;
}

public int getLeaveDays() {
return leaveDays;
}

public void setLeaveDays(int leaveDays) {
this.leaveDays = leaveDays;
}
}

接下来就是比较重要的Handler类,代码比较简单,下一个Handler的对象引用,再就是handle()和setNextHandler()方法,不多解释了,和之前的UML图中的的结构是一样的.

1
2
3
4
5
6
7
8
9
10
11
12
/**
* @ClassName: Handler
* @User: xiaomi
* @Description: //TODO
* @Time: 2019/6/26 0026 下午 1:59
* @email: a1205938863@gmail.com
*/
public interface Handler {
Optional<String> hand(LeaveNote note);
void setNextHandler(Handler nextHandler);
Boolean checkLeave(int leave);
}

然后就是他的实现类,这也是个抽象类,这个类里有个hand()方法,为了统一管理责任链的链式流程。

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
/**
* @ClassName: AbsractHandler
* @User: xiaomi
* @Description: //TODO
* @Time: 2019/6/26 0026 下午 2:02
* @email: a1205938863@gmail.com
*/
public abstract class AbsractHandler implements Handler {
private Handler handler;


@Override
public Optional<String> hand(LeaveNote note) {
if (checkLeave( note.getLeaveDays() )){
return doHand( note );
}else {
setNextHandler( handler );
return handler.hand( note );
}
}

@Override
public void setNextHandler(Handler nextHandler) {
this.handler=nextHandler;
}

protected abstract Optional<String> doHand(LeaveNote note);


和抽象类的具体实现类,这些就是责任链上的每一个点
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
/**
* @ClassName: Ceo
* @User: xiaomi
* @Description: //TODO
* @Time: 2019/6/26 0026 下午 2:12
* @email: a1205938863@gmail.com
*/
public class Ceo extends AbsractHandler {
@Override
protected Optional<String> doHand(LeaveNote note) {
String s="CEO同意!";
return Optional.ofNullable( s );
}

@Override
public Boolean checkLeave(int leave) {
return leave>3;
}

@Override
public void setNextHandler(Handler nextHandler) {
super.setNextHandler( nextHandler );
}
}
public class ClientLeader extends AbsractHandler {
@Override
protected Optional<String> doHand(LeaveNote note) {
String s="上级同意!";
return Optional.ofNullable( s );
}

@Override
public Boolean checkLeave(int leave) {
return leave<=1;
}

@Override
public void setNextHandler(Handler nextHandler) {
super.setNextHandler( nextHandler );
}
}
public class TechnologyLeader extends AbsractHandler {
@Override
protected Optional<String> doHand(LeaveNote note) {
String s="技术领导同意!";
return Optional.ofNullable( s );
}

@Override
public Boolean checkLeave(int leave) {
return leave <= 3;
}

@Override
public void setNextHandler(Handler nextHandler) {
super.setNextHandler( nextHandler );
}
}

测试一下
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
  
/**
* @ClassName: ClientLeave
* @User: xiaomi
* @Description: //责任链模式
* @Time: 2019/6/26 0026 下午 2:32
* @email: a1205938863@gmail.com
*/
public class ClientLeave {
public static void main(String[] args) {
LeaveNote leaveNote7=new LeaveNote("xiaomi","三年没回去,媳妇怀孕了",7);
LeaveNote leaveNote3=new LeaveNote("xiaomi","三年没回去,媳妇怀孕了",3);
LeaveNote leaveNote1=new LeaveNote("xiaomi","三年没回去,媳妇怀孕了",1);

Handler clientLeader=new ClientLeader();
Handler technologyLeader=new TechnologyLeader();
Handler ceo=new Ceo();
clientLeader.setNextHandler(technologyLeader );
technologyLeader.setNextHandler(ceo );
System.out.println(clientLeader.hand(leaveNote7 ).get());
System.out.println(clientLeader.hand(leaveNote3 ).get());
System.out.println(clientLeader.hand(leaveNote1 ).get());
}

}

img

3.总结

责任链的优点就在于请求者和接受者松散耦合,以及能动态组合职责。
例子中可以看出,请求者不知道接受者是谁,也不知道具体的处理过程,只需要发出请求就行了。而对于每个职责对象来说,也不关心请求者和其他的职责对象(虽然持有下一个职责对象的引用),只负责处理自己职责的部分,其他的就交给其他的职责对象去处理。
动态组合职责则是利用对于职责的拆分,可以灵活的组合形成责任链,从而可以灵活的分配职责,也可以灵活的实现职责对象。
其实会发现,为了处理一个请求,我们可能会创建很多个职责对象,但是最后实际执行的最多只有一个职责对象(甚至没有),为了兼容更多职责就需要更多地职责对象。可见细化职责的同时,我们也在不断的增加对象,这不是一个好现象;而且在职责对象中,可能需要提供默认处理,不然请求很可能不会被责任链中的任何一个职责对象处理。

1
分离职责,动态组合

转载
作者:MrTrying
链接:https://www.jianshu.com/p/b1ddd8a868e0
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

文章目录
  1. 1. 责任链模式
    1. 1.1. 1.简述
    2. 1.2. 2.案例实现
      1. 1.2.1. 场景介绍
    3. 1.3. 3.总结