推卸責任
Chain of Responsibility 模式
將多個對象組成一條職責鏈,然后按照它們在職責鏈上的順序一個一個地找出到底應該誰來負責處理。
使用 Chain of Responsibility 模式可以弱化“請求方”和“處理方”之間的關聯關系,讓雙方各自都成為可以復用的組件。
示例程序
名字 | 說明 | 角色 |
---|---|---|
Trouble | 表示發生的問題的類。它帶有問題編號(number) | |
Support | 用來解決問題的抽象類 | Handler |
NoSupport | 用來解決問題的具體類(永遠“不處理問題”) | ConcreteHandler |
LimitSupport | 用來解決問題的具體類(僅解決編號小于指定編號的問題) | ConcreteHandler |
OddSupport | 用來解決問題的具體類(僅解決奇數編號的問題) | ConcreteHandler |
SepcialSupport | 用來解決問題的具體類(僅解決指定編號的問題) | ConcreteHandler |
Main | 制作 Support 的職責鏈,制作問題并測試程序行為 | Client |
Trouble.java
package chainOfResponsibility;
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.java
package chainOfResponsibility;
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.java
package chainOfResponsibility;
public class NoSupport extends Support {
public NoSupport(String name) {
super(name);
}
protected boolean resolve(Trouble trouble) { // 解決問題的方法
return false; // 自己什么也不處理
}
}
LimitSupport.java
package chainOfResponsibility;
public class LimitSupport extends Support {
private int limit; // 可以解決編號小于 limit 的問題
public LimitSupport(String name, int limit) {
super(name);
this.limit = limit;
}
protected boolean resolve(Trouble trouble) {
if (trouble.getNumber() < limit) {
return true;
} else {
return false;
}
}
}
OddSupport.java
package chainOfResponsibility;
public class OddSupport extends Support {
public OddSupport(String name) {
super(name);
}
protected boolean resolve(Trouble trouble) {
if (trouble.getNumber() % 2 == 1) {
return true;
} else {
return false;
}
}
}
SepcialSupport.java
package chainOfResponsibility;
public class SpecialSupport extends Support {
private int number; // 只能解決指定編號的問題
public SpecialSupport(String name, int number) {
super(name);
this.number = number;
}
protected boolean resolve(Trouble trouble) {
if (trouble.getNumber() == number) {
return true;
} else {
return false;
}
}
}
Main.java
package chainOfResponsibility;
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));
}
}
}
Chain of Responsibility 模式中的角色
-
Handler(處理者)
Handler 角色定義了處理請求的接口(API)。Handler 角色知道“下一個處理者”是誰,如果自己無法處理請求,它會將請求轉給“下一個處理者”。
-
ConcreteHandler(具體的處理者)
ConcreteHandler 角色是處理請求的具體角色。
-
Client(請求者)
Client 角色是向第一個 ConcreteHandler 角色發送請求的角色。
拓展思路
一、弱化了發出請求的人和處理請求的人之間的關系。
二、可以動態的改變職責鏈。
三、專注于自己的工作。
四、推卸請求會導致處理延遲。