您的位置:首页 > 运维架构 > Tomcat

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

2016-04-26 18:57 746 查看

基本概念

定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条,并沿着这条链传递该请求,知道有对象处理它为止。

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息