设计模式-职责链模式(Reposibility)以及在JDK类库中的应用

职责链模式

定义

使多个对象都可以处理一个请求,将这个对象连成一条链,并沿着这条链传递该请求,直到其中某个对象可以处理它为止。

结构

抽象处理类:它持有自身的一个引用,定义了一个用来处理请求的接口

具体处理类:实现了抽象处理类的接口方法,在方法内部判断是否让其处理请求还是放到下一个处理类来处理。

类图

个人理解:职责链模式的思想是复合+转发的方式实现的,只不过这次复合的对象是它本身,通过持有自身的引用可以使得处理类形成一个链,在处理方法内部判断是否让下一个处理类类处理还是自身来处理。

意图:

抽象处理类:

public abstract class Handler {

	public Handler chain;

	public void setChain(Handler chain) {
		this.chain = chain;
	}
	
	public abstract void handleRequest(int request);
	
}

具体处理类:

public class ConcreteHandlerA extends Handler {

	@Override
	public void handleRequest(int request) {
		if(request > 0 && request <= 10){
			System.out.println("执行A处理方法");
		} else if (chain != null) {
			chain.handleRequest(request);
		}
	}
}
public class ConcreteHandlerB extends Handler {

	@Override
	public void handleRequest(int request) {
		if(request > 10 && request <= 20){
			System.out.println("执行B处理方法");
		} else if (chain != null) {
			chain.handleRequest(request);
		}
	}
}
public class ConcreteHandlerC extends Handler {

	@Override
	public void handleRequest(int request) {
		if(request > 20){
			System.out.println("执行C处理方法");
		}
	}

}

测试类:

	
	public static void main(String[] args) {
		Handler handlerA = new ConcreteHandlerA();
		Handler handlerB = new ConcreteHandlerB();
		Handler handlerC = new ConcreteHandlerC();
		handlerA.setChain(handlerB);
		handlerB.setChain(handlerC);
		handlerA.handleRequest(5);
		handlerA.handleRequest(11);
		handlerA.handleRequest(30);
	}
	

测试结果:

案例

我们以员工申请请假需要经过领导审批为例。组长、总监、经理作为处理审批申请的具体处理类,它们各自持有自身的引用,通过请求中请假天数判断由谁来处理审批流程。

抽象处理类:

public abstract class AbstractHandler {

	public AbstractHandler chain;
	
	public void setChain(AbstractHandler chain) {
		this.chain = chain;
	}

	public abstract void handleRequest(int request);
	
}

组长处理类:

public class TeamLeaderHandler extends AbstractHandler {

	@Override
	public void handleRequest(int request) {
		if(request>0&&request<=2){
			System.out.println("组长同意请假"+request+"天");
		}else if(chain!=null){
			chain.handleRequest(request);
		}
	}

}

总监处理类:

public class DirectorHandler extends AbstractHandler {

	@Override
	public void handleRequest(int request) {
		if(request>2&&request<=5){
			System.out.println("总监同意请假"+request+"天");
		}else if(chain!=null){
			chain.handleRequest(request);
		}
	}

}

经理处理类:

public class ManagerHandler extends AbstractHandler{

	@Override
	public void handleRequest(int request) {
		if(request>5){
			System.out.println("经理同意请假"+request+"天");
		}
	}

}

测试类:

	
	public static void main(String[] args) {
		AbstractHandler teamLeader = new TeamLeaderHandler();
		AbstractHandler director = new DirectorHandler();
		AbstractHandler manager = new ManagerHandler();
		teamLeader.setChain(director);
		director.setChain(manager);
		teamLeader.handleRequest(1);
		teamLeader.handleRequest(3);
		teamLeader.handleRequest(15);
	}
	

测试结果:

优点

1.新增具体处理类方便灵活。

2.将请求的发送者(即客户端)和请求的接受者(处理类)解耦合。

缺点

可能出现请求无法被处理的情况。

JDK类库中的职责链模式

java.util.loggingLogger#log(LogRecord ld)(暂时还不明白这个为什么会使职责链模式!

javax.servlet.Filter#doFilter(req,rep)

典型的例子是struts2的核心过滤器:StrutsPrepareAndExecuteFilter

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        try {
            prepare.setEncodingAndLocale(request, response);
            prepare.createActionContext(request, response);
            prepare.assignDispatcherToThread();
            if (excludedPatterns != null && prepare.isUrlExcluded(request, excludedPatterns)) {
                chain.doFilter(request, response);
            } else {
                request = prepare.wrapRequest(request);
                ActionMapping mapping = prepare.findActionMapping(request, response, true);
                if (mapping == null) {
                    boolean handled = execute.executeStaticResourceRequest(request, response);
                    if (!handled) {
                        chain.doFilter(request, response);
                    }
                } else {
                    execute.executeAction(request, response, mapping);
                }
            }
        } finally {
            prepare.cleanupRequest(request);
        }
    }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值