责任链模式化
定义
责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
角色
-
抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。上图中Handler类的聚合关系给出了具体子类对下家的引用,抽象方法handleRequest()规范了子类处理请求的操作。
-
具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。
示例
请求对象
public class MyRequest {
private String jsp ;
public String getJsp() {
return jsp;
}
public void setJsp(String jsp) {
this.jsp = jsp;
}
}
应答对象
public class Myresponse {
private String result;
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
}
抽象责任链对象
public abstract class Chain {
private Chain chain;
public Chain getChain() {
return chain;
}
public void setChain(Chain chain) {
this.chain = chain;
}
public abstract void doFilter(MyRequest request,Myresponse response);
}
责任链实现类A
public class ChainA extends Chain {
private String name;
public ChainA(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void doFilter(MyRequest request,Myresponse response) {
if(this.getChain() != null){
System.out.println(this.getName()+":放行请求前处理");
this.getChain().doFilter(request,response);
System.out.println(this.getName()+":放行请求后处理");
}else{
response.setResult(request.getJsp());
System.out.println(this.getName()+"处理请求,返回jsp:"+response.getResult());
}
}
}
责任链实现类B
public class ChainB extends Chain {
private String name;
public ChainB(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void doFilter(MyRequest request,Myresponse response) {
//具体实现可以不同,为了简单,这里跟chainA相同实现
if(this.getChain() != null){
System.out.println(this.getName()+":放行请求前处理");
this.getChain().doFilter(request,response);
System.out.println(this.getName()+":放行请求后处理");
}else{
response.setResult(request.getJsp());
System.out.println(this.getName()+"处理请求,返回jsp:"+response.getResult());
}
}
}
测试类
public class ChainTest {
public static void main(String[] args) {
MyRequest request = new MyRequest();
request.setJsp("index.jsp");
Myresponse response = new Myresponse();
ChainA chainA = new ChainA("chainA");
ChainB chainB = new ChainB("chainB");
chainA.setChain(chainB);
chainA.doFilter(request, response);
}
}
结果
chainA:放行请求前处理
chainB处理请求,返回jsp:index.jsp
chainA:放行请求后处理
分析
- 此例是简化了容器执行filter的过程,总所周知filter其实就是责任链的实现,前台的请求,经过一层层filter的过滤最终执行到servlet的service执行完之后再返回response,其实在tomcat中也是类似,从Engine到Host到Context再到Wrapper都是通过链传递请求;
- 测试类中首先新建一个request请求,并赋值请求jsp,chain链在接收到请求时候创建response对象,并设置每个链节点的下个节点,测试中我简单判断有下一个节点就放行(这里还可以在放行前后做一些其他操作,类似过滤器中记录日志,转码等处理),没有下一个节点就直接给response赋值result然后返回;
- 可以避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。