设计模式-责任链模式

在设计模式系列的文章中之前已经为大家分享了创建型设计模式,感兴趣的小伙伴们可以再去翻看之前的分享。接下来开始分享设计模式三大类型中的行为型模式了,今天要分享的是责任链模式。

什么是责任链模式

责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

责任链模式的结构图:
在这里插入图片描述

  • Client(客户端):实例化一个处理器的链,在第一个链对象中调用handleRequest 方法
  • Handle(处理器):抽象类,提供给实际处理器继承然后实现handleRequst方法,处理请求
  • ConcreteHandler(具体处理器):继承了handler的类,同时实现handleRequst方法,负责处理业务逻辑类,不同业务模块有不同的ConcreteHandler

代码实现责任链

假设小明要去上学,妈妈给小明列了一些上学前需要做的清单(洗头、洗脸和吃早餐),小明必须按照妈妈的要求,把清单上打钩的事情做完了才可以上学。

首先我们还是定义一个抽象 Handler 处理器,同时添加一个抽象处理方法 handleRequest,后面我只需要编写具体的处理器来继承 Handler 类

public abstract class Handler {
    protected Handler handler;

    public void setHandler(Handler handler) {
        this.handler = handler;
    }
    public abstract void handleRequest(Integer times);
}

其次构建刷牙 Handler,内部实现 handleRequest 方法,判断一下是否是当前处理应该处理的业务逻辑,不是则向下传递。

public class washHair extends Handler{
	
    @Override
    public void handleRequest(Integer times) {
        // 条件判断是否是属于当前Handler的处理范围之内,不是则向下传递Handler处理器
        if(times ==1){
          // 假设这里是处理的业务逻辑代码
            System.out.println("刷牙");
        }
        handler.handleRequest(times);
    }
}

同样的洗脸的 washFace 和 haveBreakfast 代码基本是一致的

public class washFace extends Handler{
    @Override
    public void handleRequest(Integer times) {
        if (times == 2) {
            System.out.println("洗脸");
        }
        handler.handleRequest(times);
    }
}

public class haveBreakfast extends Handler{
	
	 @Override
	    public void handleRequest(Integer times) {
	        if (times == 3) {
	            System.out.println("吃早餐");
	        }
	                handler.handleRequest(times);
	    }
}

运行结果看一下

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		    Handler first = new washFace();
	        Handler second = new washHair();
	        Handler three = new haveBreakfast();
	        first.setHandler(second);
	        second.setHandler(three);

	        //刷牙
	        first.handleRequest(1);
	        System.out.println();
	        //洗脸
	        first.handleRequest(2);
	        System.out.println();
	        //吃早餐
	        first.handleRequest(3);
	        System.out.println();
	}
刷牙

洗脸

吃早餐

这个结果可以很明显的看出,根据我们传参,不同的Handler根据自己的职责处理着自己的业务,这就是责任链。

责任链缺点

就是对DeBug不太友好,在代码逻辑比较复杂的情况下,链路比较长的情况下,Debug可能要深入很多层

应用场景

Tomcat容器:当客户端对 Web 应用发出 HTTP 请求的时候,会首先经过 Tomcat 容器的一层层过滤器(Filter),过滤器会针对请求的访问权限、参数合法性等方面进行验证和过滤,这一层一层过滤器的实现,就使用了职责链模式。

SpringMVC:客户端的 HTTP 请求到了 Web 应用之后,会被 SpringMVC 框架的 DispatcherServlet 类进行分发,分发给 Controller 层的具体方法。在进入 Controller 层的业务逻辑之前,以及执行完业务逻辑之后,该请求都会经过一系列的拦截器(Interceptor)。这一系列拦截器的处理流程,也同样是职责链模式的实现。

总结

责任链模式与 if…else 相比,他的耦合性要低一些,因为它将条件判定分散到各个处理类中,并且这些处理类的优先处理顺序可以随意的设定,并且如果想要添加新的 handler 类也是十分简单的,这符合开放闭合原则。

责任链模式带来了灵活性,但是在设置处理类前后关系时,一定要避免在链中出现循环引用的问题。

设计模式不是一成不变的,只有适合自己当前业务的模式才是最好的模式。理解前辈的思想,组合我们自己需要的模式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值