Java设计模式(七) COR(责任链)模式及Tomcat引申

基本概念

  • 定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条,并沿着这条链传递该请求,知道有对象处理它为止。
  • COR(责任链)模式的角色分工:
    • Handler:抽象处理者,定义一个处理请求的接口
    • Concrete Handler: 具体处理者,处理请求的具体类,或者传给”下家”。
    • Requester:发出请求等待处理的类,它无需关注到底是哪个具体的Handler处理它的请求
  • COR的处理问题的场景:
    • 一个request在多个handler中选择合适的进行处理
    • 传统的通过switch或者if-else进行判断,然后执行
      • 职责界定不清晰,不满足单一职责准则
      • 代码臃肿,可读性差
      • 耦合过重,Request调用具体实现,不便与Handler地拓展,丧失了面向接口编程的在实现层面低耦合的优点
      • 没有对选择逻辑进行封装,具体实现被暴露,容易出现异常
    • COR(责任链)模式,则是提供了抽象Handler接口
      • 每个具体的Handler的实现不与Requester耦合,只需要定义自己的处理级别,然后对于一个请求要么承担责任,做出回应;要么把请求转发到后续环节
      • Requester也无需知道具体为我提供服务的Handler的情况,只需提交请求即可
  • COR(责任链)模式的优缺点:
    • 优点:
      • 父类实现了请求传递的功能,子类实现请求的处理,符合单一职责原则,各个类实现一个动作或逻辑,也就是只有一个原因引起类的变化,子类的实现非常简单,责任链的建立也是非常灵活的。
      • 责任链模式屏蔽了请求的处理过程,你发起的一个请求到底是谁处理的,这个你不用关心,只要把请求抛给责任链,就会得到结果,无需关心具体由谁处理,这时责任链的核心
    • 缺点:
      • 主要的是性能问题,责任链较长时,性能会下降得很快
      • 不方便调试

例讲COR(责任链)模式

在平时的生活中,小伙伴们一起共事,经常在遇到问题时会甩锅,但是最终总是有人要背锅的,当然就是这件事的负责人了(虽然可能有时候是无辜的),但是锅是要背的,23333,那么我们来看看甩锅这段程序如何用责任链模式实现:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * Created by liulin on 16-4-26.
 */


class ErrorRequester{
    //标记请求的类型
    private String duty;

    public String getDuty() {
        return duty;
    }

    public void setDuty(String duty) {
        this.duty = duty;
    }
}

abstract class Handler{
    //记录当前责任链的下一个元素
    private Handler nextHandler;
    //标记当前子类的类型
    private String duty;
    public static final String DBA="SQL and the database";
    public static final String FRONT="HTML and CSS";
    public static final String BGD="Java and XML";

    //方便子类设置自己的类型(子类通过无参数的构造器隐藏该实现)
    public Handler ( String duty ){
        this.duty = duty;
    }

    //责任链的职责传递逻辑的实现,不支持子类的覆盖
    public final void handleMessage ( ErrorRequester requester ){
        if( requester.getDuty().equals(duty)){
            response( requester);
        }else{
            if( nextHandler != null ){
                nextHandler.handleMessage( requester );
            }else{
                System.out.println("The Error is due to others!!!");
            }
        }
    }

    public final void setNextHandler( Handler handler ){
        nextHandler = handler;
    }

    //TODO 匹配到合适的类型时的,回应请求的函数
    protected abstract void response( ErrorRequester requester );

}

class DBAHandler extends Handler{

    //设置当前子类的处理器类型
    public DBAHandler() {
        super( Handler.DBA);
    }

    //如果当前类型匹配上,那么进行响应
    @Override
    protected void response(ErrorRequester requester) {
        System.out.println( "What horrible "+ requester.getDuty() + " is!!!!");
    }
}

class BGDHandler extends Handler{


    public BGDHandler() {
        super(Handler.BGD);
    }

    @Override
    protected void response(ErrorRequester requester) {
        System.out.println("What horrible " + requester.getDuty() + " is!!!");
    }
}

class FRONTHandler extends Handler{

    public FRONTHandler() {
        super(Handler.FRONT);
    }

    @Override
    protected void response(ErrorRequester requester) {
        System.out.println("What horrible " + requester.getDuty() + " is!!!");
    }
}

public class CORTest {

    public static void main ( String [] args ){
        //构造词典
        HashMap<Integer,String> dic = new HashMap();
        dic.put ( 0 , Handler.DBA );
        dic.put ( 1 , Handler.BGD );
        dic.put ( 2 , Handler.FRONT);
        int times = 0;
        //建立责任链
        Handler dba = new DBAHandler();
        Handler bgd = new BGDHandler();
        Handler front = new FRONTHandler();
        dba.setNextHandler( bgd );
        bgd.setNextHandler( front );
        //生成随机的请求,并且响应
        while ( times++ != 10 ){
            ErrorRequester requester = new ErrorRequester();
            requester.setDuty( dic.get((int)(Math.random()*100)%3) );
            dba.handleMessage( requester );
        }
    }
}

结果如下:

这里写图片描述

Tomcat中对于COR的应用

Tomcat的容器设置就是责任链模式,从Engine到Host再到Context一知道Wraper都通过一个链传递请求。

  • 其中的角色分工:
    • Container:抽象Handler
    • StandardEngine….等: 具体Handler
  • 与标准的责任链相比引入了新的角色:
    • PipeLine:作为请求传递的管道
    • Value:在管道上对请求加工
  • 为了防止请求流不到下一个容器,每一段PipeLine总会有一个节点保证它一定能够流到下一个容器,所以每个容器都有一个StandardXXXValue
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值