责任链模式

责任链模式( chain-of-responsibility pattern)是一种由命令对象源和一系列处理对象组成的设计模式。每个处理对象都包含定义它可以处理的命令对象类型的逻辑; 其余的传递给链中的下一个处理对象。还存在一种机制,用于将新处理对象添加到该链的末尾。责任链模式在结构上与装饰器模式几乎相同,不同之处在于对于装饰器,所有类都处理请求,而对于责任链,链中的一个类恰好处理请求。

优点

  1. 避免将请求的发送方与其接收方耦合
  2. 可以使用多个接收器处理请求

类图

chain-of-responsibility pattern

handler:抽象处理者

ConcreteHandler:具体处理者,接受到请求后,可以选择处理请求或者传递给下一个处理者。

用例

假设我们有一个请假系统,不同的职位可以处理不同的请假请求,比如:

组长:可以处理三天以内的请求

厂长:可以处理七天以内的请求

老板:可以处理十五天以内的请求

如果组长可以处理,那么就直接处理了,如果组长不可以处理,那么我们再继续往下传递。

Handler.java 抽象处理器类

public abstract class Handler {
    /**
     * 下个处理者
     */
    protected Handler successor;

    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }

    public abstract void handlerRequest(int heaven);
}

GroupLeaderHandler.java

public class GroupLeaderHandler extends Handler {
    @Override
    public void handlerRequest(int heaven) {
        if (heaven <= 3) {
            System.out.println("组长处理");
        }else {
            if (super.successor != null) {
                super.successor.handlerRequest(heaven);
            }
        }
    }
}

FactoryManagerHandler.java

public class FactoryManagerHandler extends Handler{
    @Override
    public void handlerRequest(int heaven) {
        if (heaven <= 7) {
            System.out.println("厂长处理");
        }else {
            if (super.successor != null) {
                super.successor.handlerRequest(heaven);
            }
        }
    }
}

BossHandler.java

public class BossHandler extends Handler {
    @Override
    public void handlerRequest(int heaven) {
        if (heaven <= 15) {
            System.out.println("老板处理");
        }else {
            if (super.successor != null) {
                super.successor.handlerRequest(heaven);
            }
        }
    }
}

Client.java

public class Client {
    public static void main(String[] args) {
        Handler groupLeaderHandler = new GroupLeaderHandler();
        Handler factoryManagerHandler = new FactoryManagerHandler();
        Handler bossHandler = new BossHandler();
        groupLeaderHandler.setSuccessor(factoryManagerHandler);
        factoryManagerHandler.setSuccessor(bossHandler);
        //请假一天
        groupLeaderHandler.handlerRequest(1);
        //请假6天
        groupLeaderHandler.handlerRequest(6);
        //请假10天
        groupLeaderHandler.handlerRequest(10);
    }
}

Q.E.D.

知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

人生中没有四季 唯有那寒冬的荒野