设计模式之-职责链模式

145 阅读4分钟

基本概念

  1. 什么是链
  • 链是一系列节点的集合。
  • 链的各节点可灵活拆分再重组。
  1. 职责链模式
  • 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,
  • 将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止。
  1. 角色
  • 抽象处理者角色(Handler):定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。
  • 具体处理者角色(ConcreteHandler):具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。
  1. 职责链灵活在哪
  • 改变内部的传递规则 在内部,项目经理完全可以跳过人事部到那一关直接找到总经理。 每个人都可以去动态地指定他的继任者。
  • 可以从职责链任何一关开始。 如果项目经理不在,可以直接去找部门经理,责任链还会继续,没有影响。
  • 用与不用的区别 不用职责链的结构,我们需要和公司中的每一个层级都发生耦合关系。 如果反映在代码上即使我们需要在一个类中去写上很多丑陋的if….else语句。 如果用了职责链,相当于我们面对的是一个黑箱,我们只需要认识其中的一个部门,然后让黑箱内部去负责传递就好了
  1. 纯的与不纯的责任链模式 一个纯的责任链模式要求一个具体的处理者对象只能在两个行为中选择一个:一是承担责任,而是把责任推给下家。不允许出现某一个具体处理者对象在承担了一部分责任后又 把责任向下传的情况。 在一个纯的责任链模式里面,一个请求必须被某一个处理者对象所接收;在一个不纯的责任链模式里面,一个请求可以最终不被任何接收端对象所接收。 纯的责任链模式的实际例子很难找到,一般看到的例子均是不纯的责任链模式的实现。

示例

  • 代码 1.抽象处理者角色
public abstract class Handler {
    /**
     * 持有后继的责任对象
     */
    protected Handler successor;
    /**
     * 示意处理请求的方法,虽然这个示意方法是没有传入参数的
     * 但实际是可以传入参数的,根据具体需要来选择是否传递参数
     */
    public abstract void handleRequest();
    /**
     * 取值方法
     */
    public Handler getSuccessor() {
        return successor;
    }
    /**
     * 赋值方法,设置后继的责任对象
     */
    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }
    
}

2.具体处理者角色

public class ConcreteHandler extends Handler {
    /**
     * 处理方法,调用此方法处理请求
     */
    @Override
    public void handleRequest() {
        /**
         * 判断是否有后继的责任对象
         * 如果有,就转发请求给后继的责任对象
         * 如果没有,则处理请求
         */
        if(getSuccessor() != null)
        {            
            System.out.println("放过请求");
            getSuccessor().handleRequest();            
        }else
        {            
            System.out.println("处理请求");
        }
    }
 
}

3.客户端类

public class Client {
 
    public static void main(String[] args) {
        //组装责任链
        Handler handler1 = new ConcreteHandler();
        Handler handler2 = new ConcreteHandler();
        handler1.setSuccessor(handler2);
        //提交请求
        handler1.handleRequest();
    }
}
  • 说明 可以看出,客户端创建了两个处理者对象,并指定第一个处理者对象的下家是第二个处理者对象,而第二个处理者对象没有下家。然后客户端将请求传递给第一个处理者对象。 由于本示例的传递逻辑非常简单:只要有下家,就传给下家处理;如果没有下家,就自行处理。 因此,第一个处理者对象接到请求后,会将请求传递给第二个处理者对象。由于第二个处理者对象没有下家,于是自行处理请求。活动时序图如下所示。

参考

结语

欢迎关注微信公众号『码仔zonE』,专注于分享Java、云计算相关内容,包括SpringBoot、SpringCloud、微服务、Docker、Kubernetes、Python等领域相关技术干货,期待与您相遇!