1、职责链模式
职责链可以是一条直线、一个环或者一个树形结构,最常见的职责链是直线型,即沿着一条单向的链来传递请求。链上的每一个对象都是请求处理者,职责链模式可以将请求的处理者组织成一条链,并让请求沿着链传递,由链上的处理者对请求进行相应的处理,客户端无须关心请求的处理细节以及请求的传递,只需将请求发送到链上即可,实现请求发送者和请求处理者解耦。
职责链模式
:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。职责链模式是一种对象行为型模式。
职责链模式的核心是引入抽象处理者。
组成:
1)
Handler
(抽象处理者)
:它定义了一个处理请求的接口,一般设计为抽象类,由于不同的具体处理者处理请求的方式不同,因此在其中定义了抽象请求处理方法。因为每一个处理者的下家还是一个处理者,因此在抽象处理者中定义了一个抽象处理者类型的对象
,作为其对下家的引用。通过该引用,处理者可以连成一条链。
2)
ConcreteHandler(具体处理者)
:它是抽象处理者的子类,可以处理用户请求,在具体处理者类中实现了抽象处理者中定义的抽象请求处理方法,在处理请求之前需要进行判断,看是否有相应的处理权限,如果可以处理请求就处理它,否则将请求转发给后继者;在具体处理者中可以访问链中下一个对象,以便请求的转发。
类图:
在职责链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得
系统可以在不影响客户端的情况下动态地重新组织链和分配责任
。
代码:
abstract class Handler{
protected Handler successor ;
protected void handleRequest() {
//
}
public Handler getSuccessor() {
return successor;
}
public void setSuccessor(Handler successor) {
this.successor = successor;
}
}
class ConcreteHandler1 extends Handler{
protected void handleRequest() {
if(请求条件满足){
//处理业务逻辑
}else{
//条件不满足,交由下级链处理
successor.handleRequest();
}
}
}
适用场景: 职责链模式适用以下
场景
1)
有多个对象可以处理同一个请求,具体哪个对象处理该请求待运行时刻再确定,客户端只需将请求提交到链上,而无须关心请求的处理对象是谁以及它是如何处理的。
2)
在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
总结:
职责链模式通过建立一条链来组织请求的处理者,请求将沿着链进行传递,请求发送者无须知道请求在何时、何处以及如何被处理,实现了请求发送者与处理者的解耦。在软件开发中,如果遇到有多个对象可以处理同一请求时可以应用职责链模式,例如在Web应用开发中创建一个过滤器(Filter)链来对请求数据进行过滤,在工作流系统中实现公文的分级审批等等,使用职责链模式可以较好地解决此类问题。
2、JDK中职责链模式的应用
在java
Web
应用开发中,Filter是职责链(过滤器)模式的典型应用,以下是Filter的模拟实现分析:
- 1) 模拟web请求Request以及web响应Response
public interface Request{
}
public interface Response{
}
- 2) 模拟web过滤器Filter
public interface Filter {
public void doFilter(Request req,Response res,FilterChain c);
}
- 3) 模拟实现具体过滤器
class ConcreteFilter1 implements Filter{
@Override
public void doFilter(Request req, Response res, FilterChain c) {
// TODO Auto-generated method stub
//过滤前置处理业务代码
System.out.println("过滤器1 前置处理");
c.doFilter(req, res); //在这里它会调用过滤链中的下一个filter
//过滤后置处理业务代码
System.out.println("过滤器1 后置处理");
}
}
class ConcreteFilter2 implements Filter{
@Override
public void doFilter(Request req, Response res, FilterChain c) {
// TODO Auto-generated method stub
//过滤前置处理业务代码
System.out.println("过滤器2 前置处理");
c.doFilter(req, res);//在这里它会调用过滤链中的下一个filter
//过滤后置处理业务代码
System.out.println("过滤器2 后置处理");
}
}
- 4) 模拟实现过滤器链FilterChain
public static class FilterChain {
private ArrayList<Filter> filterList = new ArrayList<Filter>();
private int index = 0 ;
public FilterChain addFilter(Filter f){
filterList.add(f);
return this;
}
public boolean removeFilter(Filter f){
return filterList.remove(f);
}
public void doFilter(Request req, Response res) {
// TODO Auto-generated method stub
if(index >= filterList.size()){
return ;
}
else{
//依次执行下一个过滤器,直到整个过滤器链执行完
Filter f = filterList.get(index);
index ++;
f.doFilter(req, res, this);
}
}
}
测试:
public static void main(String[] args) {
Request req = null;
Response res = null ;
FilterChain filterChain = new FilterChain();
Filter f1 = new ConcreteFilter1();
Filter f2 = new ConcreteFilter2();
filterChain.addFilter(f1);
filterChain.addFilter(f2);
filterChain.doFilter(req, res);
}