责任链模式
Posted Michael2397
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了责任链模式相关的知识,希望对你有一定的参考价值。
参考:http://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.html
责任链模式涉及到的角色如下所示:
● 抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。上图中Handler类的聚合关系给出了具体子类对下家的引用,抽象方法handleRequest()规范了子类处理请求的操作。
● 具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。
/DesignPatterns/src/com/louis/chain/Handler.java
/** * Project Name:DesignPatterns * File Name:Handler.java * Package Name:com.louis.chain * Date:2017年11月5日下午8:13:45 * Copyright (c) 2017, 2692613726@qq.com All Rights Reserved. * */ package com.louis.chain; /** * ClassName:Handler * Function: TODO ADD FUNCTION. * Reason: TODO ADD REASON. * Date: 2017年11月5日 下午8:13:45 * @author michael * @version * @since JDK 1.7 * @see */ public abstract class Handler { //持有后继的责任对象 protected Handler successor; /* * 实例处理请求的方法,实际可以有传入值得 * */ public abstract void handleRequest(); /* * 取值方法 * */ public Handler getSuccessor(){ return successor; } /* * 复制方法,设置后继的责任对象 * */ public void setSuccessor(Handler successor){ this.successor = successor; } }
/DesignPatterns/src/com/louis/chain/ConcreteHandler.java
/** * Project Name:DesignPatterns * File Name:ConcreteHandler.java * Package Name:com.louis.chain * Date:2017年11月5日下午8:18:26 * Copyright (c) 2017, 2692613726@qq.com All Rights Reserved. * */ package com.louis.chain; /** * ClassName:ConcreteHandler * Function: TODO ADD FUNCTION. * Reason: TODO ADD REASON. * Date: 2017年11月5日 下午8:18:26 * @author michael * @version * @since JDK 1.7 * @see */ public class ConcreteHandler extends Handler { /** * 处理方法,调用此方法处理请求 */ @Override public void handleRequest() { /* * 判断是否有后继的责任对象,如果有,就转发请求给后继的责任对象 * 如果没有,则处理请求 * */ if(getSuccessor()!=null){ System.out.println("放过请求"); getSuccessor().handleRequest(); }else{ System.out.println("处理请求"); } } }
/DesignPatterns/src/com/louis/chain/Client.java
/** * Project Name:DesignPatterns * File Name:Clent.java * Package Name:com.louis.chain * Date:2017年11月5日下午8:23:47 * Copyright (c) 2017, 2692613726@qq.com All Rights Reserved. * */ package com.louis.chain; /** * ClassName:Clent * Function: TODO ADD FUNCTION. * Reason: TODO ADD REASON. * Date: 2017年11月5日 下午8:23:47 * @author michael * @version * @since JDK 1.7 * @see */ public class Client { public static void main(String[] args) { Handler handler1 = new ConcreteHandler(); Handler handler2 = new ConcreteHandler(); handler1.setSuccessor(handler2); //提交请求 handler1.handleRequest(); } }
使用场景:申请聚餐费用的管理
当某人提出聚餐费用申请的请求后,该请求会在 项目经理—〉部门经理—〉总经理 这样一条领导处理链上进行传递,发出请求的人并不知道谁会来处理他的请求,每个领导会根据自己的职责范围,来判断是处理请求还是把请求交给更高级别的领导,只要有领导处理了,传递就结束了。
/DesignPatterns/src/com/louis/chain/company/Handler.java
/** * Project Name:DesignPatterns * File Name:Handler.java * Package Name:com.louis.chain.company * Date:2017年11月5日下午8:27:56 * Copyright (c) 2017, 2692613726@qq.com All Rights Reserved. * */ package com.louis.chain.company; /** * ClassName:Handler * Function: TODO ADD FUNCTION. * Reason: TODO ADD REASON. * Date: 2017年11月5日 下午8:27:56 * @author michael * @version * @since JDK 1.7 * @see */ public abstract class Handler { //持有下一个处理请求的对象 protected Handler successor = null; /* * 取值方法 * */ public Handler getSuccessor(){ return successor; } /* * 设置下一个处理请求的对象 * */ public void setSuccessor(Handler successor){ this.successor = successor; } /* * 处理餐费的申请 * @param user 申请人 * @param fee 申请的钱数 * @return 成功或失败的具体通知 * */ public abstract String handFeeRequest(String user,double fee); }
/DesignPatterns/src/com/louis/chain/company/ProjectManager.java
/** * Project Name:DesignPatterns * File Name:ProjectManager.java * Package Name:com.louis.chain.company * Date:2017年11月5日下午8:35:06 * Copyright (c) 2017, 2692613726@qq.com All Rights Reserved. * */ package com.louis.chain.company; /** * ClassName:ProjectManager * Function: TODO ADD FUNCTION. * Reason: TODO ADD REASON. * Date: 2017年11月5日 下午8:35:06 * @author michael * @version * @since JDK 1.7 * @see */ public class ProjectManager extends Handler{ @Override public String handFeeRequest(String user,double fee) { String str = ""; //项目经理权限比较小,只能在500以内 if (fee<500) { //为了测试简单,只同意张三的请求 if("张三".equals(user)) { str = "成功:项目经理同意【" + user + "】的聚餐费用,金额为" + fee + "元"; }else { //其他人一律不同意 str = "失败:项目经理不同意【" + user + "】的聚餐费用,金额为" + fee + "元"; } }else { //超过500,继续传递给更高级别的人处理 if(getSuccessor()!=null){ return getSuccessor().handFeeRequest(user, fee); } } return str; } }
/DesignPatterns/src/com/louis/chain/company/DeptManager.java
/** * Project Name:DesignPatterns * File Name:DeptManager.java * Package Name:com.louis.chain.company * Date:2017年11月5日下午8:41:25 * Copyright (c) 2017, 2692613726@qq.com All Rights Reserved. * */ package com.louis.chain.company; /** * ClassName:DeptManager * Function: TODO ADD FUNCTION. * Reason: TODO ADD REASON. * Date: 2017年11月5日 下午8:41:25 * @author michael * @version * @since JDK 1.7 * @see */ public class DeptManager extends Handler { @Override public String handFeeRequest(String user, double fee) { String str = ""; //部门经理的权限只能在1000以内 if(fee < 1000) { //为了测试,简单点,只同意张三的请求 if("张三".equals(user)) { str = "成功:部门经理同意【" + user + "】的聚餐费用,金额为" + fee + "元"; }else { //其他人一律不同意 str = "失败:部门经理不同意【" + user + "】的聚餐费用,金额为" + fee + "元"; } }else { //超过1000,继续传递给级别更高的人处理 if(getSuccessor() != null) { return getSuccessor().handFeeRequest(user, fee); } } return str; } }
/DesignPatterns/src/com/louis/chain/company/GeneralManager.java
/** * Project Name:DesignPatterns * File Name:GeneralManager.java * Package Name:com.louis.chain.company * Date:2017年11月5日下午8:44:57 * Copyright (c) 2017, 2692613726@qq.com All Rights Reserved. * */ package com.louis.chain.company; /** * ClassName:GeneralManager * Function: TODO ADD FUNCTION. * Reason: TODO ADD REASON. * Date: 2017年11月5日 下午8:44:57 * @author michael * @version * @since JDK 1.7 * @see */ public class GeneralManager extends Handler { @Override public String handFeeRequest(String user, double fee) { String str = ""; //总经理的权限很大,只要请求到了这里,他都可以处理 if(fee >= 1000) { //为了测试,简单点,只同意张三的请求 if("张三".equals(user)) { str = "成功:总经理同意【" + user + "】的聚餐费用,金额为" + fee + "元"; }else { //其他人一律不同意 str = "失败:总经理不同意【" + user + "】的聚餐费用,金额为" + fee + "元"; } }else { //如果还有后继的处理对象,继续传递 if(getSuccessor() != null) { return getSuccessor().handFeeRequest(user, fee); } } return str; } }
/DesignPatterns/src/com/louis/chain/company/Client.java
/** * Project Name:DesignPatterns * File Name:Client.java * Package Name:com.louis.chain.company * Date:2017年11月5日下午8:45:39 * Copyright (c) 2017, 2692613726@qq.com All Rights Reserved. * */ package com.louis.chain.company; /** * ClassName:Client Function: TODO ADD FUNCTION. Reason: TODO ADD REASON. Date: * 2017年11月5日 下午8:45:39 * * @author michael * @version * @since JDK 1.7 * @see */ public class Client { public static void main(String[] args) { // 先要组装责任链 Handler h1 = new GeneralManager(); Handler h2 = new DeptManager(); Handler h3 = new ProjectManager(); h3.setSuccessor(h2); h2.setSuccessor(h1); // 开始测试 String test1 = h3.handFeeRequest("张三", 300); System.out.println("test1 = " + test1); String test2 = h3.handFeeRequest("李四", 300); System.out.println("test2 = " + test2); System.out.println("---------------------------------------"); String test3 = h3.handFeeRequest("张三", 700); System.out.println("test3 = " + test3); String test4 = h3.handFeeRequest("李四", 700); System.out.println("test4 = " + test4); System.out.println("---------------------------------------"); String test5 = h3.handFeeRequest("张三", 1500); System.out.println("test5 = " + test5); String test6 = h3.handFeeRequest("李四", 1500); System.out.println("test6 = " + test6); } }
纯的与不纯的责任链模式
在一个纯的责任链模式里面,一个请求必须被某一个处理者对象所接收;在一个不纯的责任链模式里面,一个请求可以最终不被任何接收端对象所接收。纯的责任链模式的实际例子很难找到,一般看到的例子均是不纯的责任链模式的实现。
责任链模式在Tomcat中的应用
详细参考:http://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.html
以上是关于责任链模式的主要内容,如果未能解决你的问题,请参考以下文章