LoginSignup
0
0

More than 3 years have passed since last update.

Chain Of Responsibilityパターン

Posted at

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 + "]";
     }
}

実行結果

スクリーンショット 2020-09-17 18.22.06.png

こちらを参考にさせていただきました。
増補改訂版Java言語で学ぶデザインパターン入門

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0