情景引入
我们首先看看什么是推卸责任。假设现在我们要去公司领取资料。首先我们向公司前台打听要
去哪里领取资料,她告诉我们应该去“营业窗口”。然后等我们到了“营业窗口”后,又被告知应
该去“售后部门”。等我们好不容易赶到了“售后部门”,又被告知应该去“资料中心”,因此最后
我们又不得不赶往“资料中心”。像这样,在找到合适的办事人之前,我们被不断地踢给一个又一
个人,这就是“推卸责任”。
“推卸责任”听起来有些贬义的意思,但是有时候也确实存在需要“推卸责任”的情况。例如,
当外部请求程序进行某个处理,但程序暂时无法直接决定由哪个对象负责处理时,就需要推卸责
任。这种情况下,我们可以考虑将多个对象组成一条职责链,然后按照它们在职责链上的顺序一个
一个地找出到底应该谁来负责处理。
这种模式被称为Chain of Responsibility 模式。Responsibility有 “责任”的意思,在汉语中,
该模式称为“职责链”。总之,我们可以将它想象为推卸责任的结构,这有利于大家记住这种模式。
使用Chain of Responsibility模式可以弱化“请求方”和“处理方”之间的关联关系,让双方各
自都成为可独立复用的组件。此外,程序还可以应对其他需求,如根据情况不同,负责处理的对象
也会发生变化的这种需求。
当一个人被要求做什么事情时,如果他可以做就自己做,如果不能做就将“要求”转给另外一
个人。下一个人如果可以自己处理,就自己做;如果也不能自己处理,就再转给另外- …..这
就是Chain of Responsibility模式。
示例程序
功能描述
处理某个问题
类的一览表
名字 |
说明 |
Trouble |
表示发生的问题的类。它带有问题编号( number ) |
Support |
用来解决问题的抽象类 |
NoSupport |
用来解决问题的具体类(永远“不处理问题” ) |
LimitSupport |
用来解决问题的具体类(仅解决编号小于指定编号的问题) |
OddSupport |
用来解决问题的具体类(仅解决奇数编号的问题) |
SpecialSupport |
用来解决问题的具体类(仅解决指定编号的问题) |
Main |
制作Support的职责链,制造问题并测试程序行为 |
UML

主要代码
Trouble 类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class Trouble { private int number; public Trouble(int number) { this.number = number; }
public int getNumber() { return number; }
public String toString() { return " [Trouble" + number + "]";
} }
|
Support 类
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
| 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); } }
public String toString() {
return "[" + name + "]"; }
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 +"cannot be resolved.") ; } }
|
NoSupport 类
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; } }
|
LimitSupport 类
1 2 3 4 5 6 7 8 9 10 11 12
| 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) { return trouble.getNumber() < limit; } }
|
OddSupport 类
1 2 3 4 5 6 7 8 9 10 11
| public class OddSupport extends Support {
public OddSupport(String name) { super(name); }
@Override protected boolean resolve(Trouble trouble) { return trouble.getNumber() % 2 == 1; } }
|
SpecialSupport 类
1 2 3 4 5 6 7 8 9 10 11 12
| 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) { return trouble.getNumber() == number; } }
|
Main 类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class Main { public static void main(String[] args) { Support alice = new NoSupport("Alice"); Support bob = new LimitSupport("Bob", 100); Support charlie = new SpecialSupport("Charlie", 429); Support diana = new LimitSupport("Diana", 200); Support elmo = new OddSupport("Elmo"); Support fred = new LimitSupport("Fred", 300);
alice.setNext(bob).setNext(charlie).setNext(diana).setNext(elmo).setNext(fred);
for (int i = 0; i < 500; i += 33) { alice.support(new Trouble(i));
} } }
|