职责链就是,将不属于自己职责的任务推卸给下一个执行任务的对象。我们将多个这样的对象组成一条链,然后根据组成顺序,任务就能被分配到具体执行的对象上。

首先,定义一个表示用来解决问题的抽象类Support

public abstract class Support {
    private String name;
    //推卸给的对象
    private Support next;

    public Support(String name) {
        this.name = name;
    }

    //这个总是返回最新的职责对象,和build很像
    public Support setNext(Support support) {
        next = support;
        return next;
    }

    //解决问题的方法,各个子类需要自己实现
    protected abstract boolean resolve(Trouble trouble);

    //问题解决
    protected void done(Trouble trouble) {
        System.out.println(trouble + "问题已经由" + this + "解决");
    }

    protected void fail(Trouble trouble) {
        System.out.println(trouble + "问题未解决");
    }

    //解决问题的步骤
    public final void support(Trouble trouble) {
        if (resolve(trouble)) {
            done(trouble);
        } else if (next != null) {
            //让他的下一个support解决,链式调用
            next.support(trouble);
        } else {
            fail(trouble);
        }
    }

    public String toString() {
        return "[" + name + "]";
    }
}

接着再定义一个问Trouble

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

然后再定义具体去解决问题的类,继承于Support,重写resolve方法:

  • LimitSupport 解决编号小于Limit的问题.
  • SpecialSupport 解决特定编号的问题.
  • NoSupport 不解决问题.
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;
    }
}
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;
    }
}
public class NoSupport extends Support {
    private String name;
    public NoSupport(String name) {
        super(name);
    }

    @Override
    protected boolean resolve(Trouble trouble) {
        return false;
    }
}

最后进行使用:

public class Main {
    public static void main(String[] args) {
        Support alias = new NoSupport("alias");
        Support bob = new LimitSupport("bob", 20);
        Support elmo = new SpecialSupport("elmo", 30);
        Support fred = new LimitSupport("fred", 50);

        //形成职责链
        alias.setNext(bob).setNext(elmo).setNext(fred);
        //制造问题
        for (int i = 10; i < 55; i++) {
            alias.support(new Trouble(i));
        }
    }
}

职责链的核心在于Support类中的next,以及定义的support方法,在调用resolve处理问题返回false时,调用next,将问题推给下一个对象进行处理。

职责链模式
解决更多的是 条件属于模糊的判断,执行不同的逻辑,比如if(true || false) / else if() /…将判断条件内置于函数中,条件不符合需要链式传递继续执行函数

策略模式
有确定的判断条件,比如switch...case直接根据确定的判断条件调用