Chain of Responsibilityパターンとは
複数のオブジェクトを鎖のように繋いでおき、
そのオブジェクトの鎖を順次渡り歩いて目的のオブジェクトを決定する方法。
要求に対し、処理できるものなら処理し、処理できない場合は
次にたらい回しする。その次もまたたらい回していく…といったパターン。
Handler(処理者)の役
要求を処理するインターフェースを定める役。
次の人を保持しておき、自分が処理できない要求がきたら、その人にたらい回しする。
次の人もHandler役。
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);
}
}
@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.");
}
}
ConcreteHandler(具体的処理者)の役
要求を処理する具体的な役。
package chainOfResponsibility;
public class NoSupport extends Support{
public NoSupport(String name) {
super(name);
}
@Override
protected boolean resolve(Trouble trouble) {
return false;
}
}
package chainOfResponsibility;
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;
}
}
package chainOfResponsibility;
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;
}
}
package chainOfResponsibility;
public class OddSupport extends Support{
public OddSupport(String name) {
super(name);
}
@Override
protected boolean resolve(Trouble trouble) {
return trouble.getNumber() % 2 == 0;
}
}
Client(要求者)の役
最初のConcreteHandler役に要求をだす役。
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));
}
}
}
トラブルを表すクラス
package chainOfResponsibility;
public class Trouble {
private int number;
public Trouble(int number) {
this.number = number;
}
public int getNumber() {
return number;
}
@Override
public String toString() {
return "[Trouble " + number + "]";
}
}
実行結果
こちらを参考にさせていただきました。
増補改訂版Java言語で学ぶデザインパターン入門