职责链模式

职责链模式

一、职责链模式是什么?

职责链模式(Chain of Responsibility Design 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.

职责链的几个特点:

  • 存在多个接收者可以处理请求
  • 请求只需被某个接收者处理即可
  • 请求也可以被多个接收者处理

职责链的目的在于,找到一个可以处理请求的接收者就好了。

二、为什么要用职责链模式?

2.1 想要运行时确定请求接收者

如果谁负责处理某个请求是不确定的,而是想要在运行时确定,可以尝试用职责链。

2.2 想要动态增删处理者

想要在运行时动态添加和删除,或者自定义接收处理,可以用职责链模式。

2.3 想要按优先级处理请求

如果想要根据请求类型,按照某种优先级处理,可以使用职责链模式。

可以按优先级处理,是职责链一个重要的特性。

三、职责链模式怎么用?

职责链模式可以分为2种情况:

  • 只要有一个接收者处理请求,职责链就停止了
  • 所有接收者都可以处理请求,直到职责链结束

具体使用哪种形式,看实际的需求。

职责链模式中出现的角色:

  • 处理者(Handler):定义职责链中处理器的接口
  • 具体处理者(ConcreteHandler):实现了处理者接口的具体实现,是实际处理请求的接收者
  • 请求者(Client):发送请求的角色

职责链结构:

职责链结构

示例程序结构:

职责链结构

处理者接口(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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public abstract class Support {

private String name;
private Support next;

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

public Support setNext(Support next) {
this.next = next;
return next;
}

/**
* 解决问题的步骤
*/
public final void support(Trouble trouble) {
if (resolve(trouble)) {
done(trouble);
} else if (next != null) {
next.support(trouble);
} else {
fail(trouble);
}
}

/**
* 解决问题的方法
*/
protected abstract boolean resolve(Trouble trouble);

protected void done(Trouble trouble) {
System.out.println(trouble + " is resolved by " + this + ".");
}

protected void fail(Trouble trouble) {
System.out.println(trouble + " can not be resolved.");
}

public String toString() {
return "[" + name + "]";
}

}

具体处理者(ConcreteHandler):

1
2
3
4
5
6
7
8
9
10
11
12
public class NoSupport extends Support {

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

@Override
protected boolean resolve(Trouble trouble) {
return false;
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class OddSupport extends Support {

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

@Override
protected boolean resolve(Trouble trouble) {
if (trouble.getNumber() % 2 == 1) {
return true;
}
return false;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class LimitSupport extends Support {

private int limit;

public LimitSupport(String name, int limit) {
super(name);
this.limit = limit;
}

@Override
protected boolean resolve(Trouble trouble) {
if (trouble.getNumber() < limit) {
return true;
}
return false;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class SpecialSupport extends Support {

private int number;

public SpecialSupport(String name, int number) {
super(name);
this.number = number;
}

@Override
protected boolean resolve(Trouble trouble) {
if (trouble.getNumber() == number) {
return true;
}
return false;
}
}

四、职责链模式有什么优缺点?

优点:

  • 请求和接收解耦,可扩展性好
  • 接收者可以动态调整,灵活性好
  • 每个接收者的职责唯一,符合单一职责原则

缺点:

  • 职责链可能存在有序性,接收者不能随意调整,否则容易出问题
  • 职责链需要注意循环链接的问题
  • 职责链可能比较长,影响效率
作者

jiaduo

发布于

2022-01-20

更新于

2023-04-03

许可协议