Chain of Responsibility模式
将多個對象組成一條責任鍊,然後按照它們在職責鍊上的順序一個一個地找出到底應該誰來負責處理。這種模式被稱為Chain of Responsibility模式。我們一般稱為“職責鍊”。
示例程式
示例程式類圖
Trouble
public class Trouble {
// 問題編号
private int number;
// 生成問題
public Trouble(int number) {
this.number = number;
}
/**
* 擷取問題編号
*
* @return
*/
public int getNumber() {
return number;
}
/**
* 代表問題的字元串
* @return
*/
@Override
public String toString() {
return "[Trouble " + number + "]";
}
}
Support
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 void support(Trouble trouble) { // 解決問題的步驟
if (resolve(trouble)) {
done(trouble);
} else if (next != null) {
next.support(trouble);
} else {
fail(trouble);
}
}
@Override
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
public class NoSupport extends Support {
public NoSupport(String name) {
super(name);
}
@Override
protected boolean resolve(Trouble trouble) { // 解決問題的方法
return false; // 自己什麼也不處理
}
}
LimitSupport
public class LimitSupport extends Support {
private int limit; // 可以解決編号小于limit的問題
public LimitSupport(String name, int limit) { // 構造函數
super(name);
this.limit = limit;
}
@Override
protected boolean resolve(Trouble trouble) { // 解決問題的方法
if (trouble.getNumber() < limit) {
return true;
} else {
return false;
}
}
}
OddSupport
public class OddSupport extends Support {
public OddSupport(String name) { // 構造函數
super(name);
}
@Override
protected boolean resolve(Trouble trouble) { // 解決問題的方法
if (trouble.getNumber() % 2 == 1) {
return true;
} else {
return false;
}
}
}
SpecialSupport
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;
} else {
return false;
}
}
}
Main
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模式中登場的角色
1.Handler(處理者)
Handler角色定義了處理請求的接口(API)。Handler角色知道“下一個處理者”是誰,如果自己無法處理請求,它會将請求轉給“下一個處理者”。當然,“下一個處理者”也是Handler角色。在示例程式中,由Support類扮演此角色。負責處理請求的是support方法。
2.ConcreteHandler(具體的處理者)
ConcreteHandler角色是處理請求的具體角色。在示例程式中,由NoSupport、LimitSupport、OddSupport、SpecialSupport等多個類扮演此角色。
3.Client(請求者)
Client角色是向第一個ConcreteHandler角色發送請求的角色。